Помогите разобраться с антиддос скриптом

vitom

Новичок
Здравствуйте. Собственно вот нашел скрипт, анализирует количество обращений к сайту за 20 секунд, если количество обращений больше 10 - то выводит табличку о недоступности.

Этот файл открывают пользователи: index.php
PHP:
<?

// пример использования скрипта Klavasoft AntiDDOS

include "$_SERVER[DOCUMENT_ROOT]/path/to/ks_antiddos.php";
$ksa = new ks_antiddos();

// скрипт анализирует активность текущего ИПа за последние $seconds_limit секунд
$seconds_limit = 20;
// считая заходы свыше $hit_limit - подлежащими блокированию
$hits_limit = 10;

// скрипт определяет статус посетителя ($ks->visitor) как:
// raw  - посетитель бы по каким-либо причинам не обработан скриптом
// new  - это первый заход посетителя за последние $seconds_limit секунд
// cool - количество заходов посетителя - от 2 до $ksa->warm_level
// hot  - количество заходов больше чем hits_limit и посетитель должен быть заблокирован (приостановлен)

// опционально можно сделать настройки
$ksa->auto = false; 	// не проводить блокирования hot-посетителей скриптом (вы предполагаете сами это сделать)
$ksa->warm_level = 3; 	// значение warm_level по умолчанию - $hits_limit/2
$ksa->delay = 10; 		// предлагать 'hot' посетителю вернуться через $ksa->delay секунд
						// значение по умолчанию - 20


// определяем статус посетителя
$ksa->doit($seconds_limit,$hits_limit);
// если вы не сбросили значение поля $ksa->auto и статус посетителя $ksa->visitor=='hot'
// то скрипт отправит браузеру headers and HTML которые организуют задержку перед повторным запросом.

// если $ksa->auto == false, то проверяем надо ли банить посетителя 
if ($ksa->visitor=='hot') 
{
	header('HTTP/1.0 503 Service Unavailable');
	header('Status: 503 Service Unavailable');
	header('Retry-After: 30');
	die('sleep');
}

$lite_version = $ksa->visitor=='warm'; 	// по этой переменной можно отдавать "теплым" посетителям
										// облегченную версию сайта

?>

Этот файл инклудится: ks_antiddos.php

PHP:
<?

//----------------------------------------
// KlavaSoft AntiDDOS ver. 3.0
// (C) Cosinus, Klavasoft.com
// http://klavasoft.com/antiddos
//----------------------------------------




class ks_antiddos
{
	var $seconds_limit, $hits_limit, $memlen;
	var $status, $error_msg, $now;
	var $visitor; // статус визитора
	var $warm_level; // количиство хитов за seconds_limit секундпри котором статус визитора устанавливается в warm
	var $iplist_var = 1; // номер переменной списка в шареде
	var $auto = true; 
	var $delay = 20; // задержка предлагаемая блокируемым визиторам
	var $block_cnet = true; // блокировать всю сеть класса C

	function doit($seconds_limit,$hits_limit,$memlen=100000)
	{
		if (!function_exists('shm_attach')) return $this->alles(false);
		$this->seconds_limit = $seconds_limit;
		$this->hits_limit = $hits_limit;
		$this->memlen = $memlen;
		$this->visitor = 'raw'; // необработан
		if (empty($this->warm_level)) 
			$this->warm_level = $this->hits_limit/2;
		$this->now = time();
	// читаем список
		if (false===$this->read_iplist()) return $this->alles(false);
	// прочистка списка
		$this->clean_list();
	// добавляем этот заход
		$ip = $_SERVER['REMOTE_ADDR'];
		if ($this->block_cnet) $ip = substr($ip,0,strrpos($ip,'.')+1);
		if (@!is_array($this->iplist[$ip])) $this->iplist[$ip] = array();
		$this->iplist[$ip][] = $this->now;
	// сохраняем список
		if (false===$this->save_iplist()) return $this->alles(false);
		$count = count($this->iplist[$ip]);
		$this->status = 'ok';
		if ($count==1) // если есть только этот заход в массиве
			$this->visitor = "new";
		elseif ($count>$this->hits_limit)
			$this->visitor = "hot";
		elseif ($count>=$this->warm_level) 
			$this->visitor = "warm";
		else
			$this->visitor = "cool";
		return $this->alles(true);
	}

// прочистка списка	
	function clean_list()
	{
		foreach($this->iplist as $ip=>$times)
		{
			$times_count = count($times);
		// исщем заход, который надо оставить вместе с последующими
			$actual_ptr = -1;
			for($i=0; $i<$times_count; $i++)
			{
				if ($times[$i]+$this->seconds_limit>$this->now)
				{ // нашли
					$actual_ptr = $i;
					break;
				}
			}
			if ($actual_ptr==-1) // очищаем ИП
			{
				unset($this->iplist[$ip]);
				continue;
			}
			else
			{
				$actual_ptr = max($actual_ptr,$times_count-$this->hits_limit);
				$this->iplist[$ip] = array_slice($times,$actual_ptr);
			}
			
		}
	}
	
	
	function read_iplist()
	{
	// подключаемся к памяти
		$shm_token = ftok(__FILE__,' ');
		$this->shm_id = shm_attach($shm_token,$this->memlen,0766);
		if (false===$this->shm_id) 
		{
			$this->status = 'error';
			$this->error_msg = 'cannot attach shared memory. ';
			return false;
		}
		$this->iplist = @shm_get_var($this->shm_id,$this->iplist_var);
		if (false===$this->iplist)
		{ // создаем переменную в шареде
			$this->iplist = array();
			$res = @shm_put_var($this->shm_id,$this->iplist_var,$this->iplist);
			if (false===$res) 
			{
				$this->status = 'error';
				$this->error_msg = 'cannot create shared iplist. ';
				return false;
			}
		}
		return true;
	}
	
	function save_iplist()
	{
		$res = true;
		if (false===shm_put_var($this->shm_id,$this->iplist_var,$this->iplist)) $res = false;
		return $res;
	}
	
	function getmicrotime() 
	{ 
		list($usec, $sec) = explode(" ", microtime()); 
		return ((float)$usec + (float)$sec); 
	} 	
	
	function alles($res=true)
	{
		if (!empty($this->shm_id)) 
		{
			if (false===@shm_detach($this->shm_id)) 
				$this->error_msg .= '; error detaching shared memory. ';
		}
		if (!empty($this->error_msg) )
		{
			$this->status = 'error';
			$res = false;
		}
		if ($this->auto && $this->visitor=='hot')
		{
			header('HTTP/1.0 503 Service Unavailable');
			header('Status: 503 Service Unavailable');
			header("Retry-After: $this->delay");
			print "<html><meta http-equiv='refresh' content='$this->delay'><body><h2>Our server is currently overloaded, your request will be repeated automatically in $this->delay seconds</h2>";
			die();
		}
		return $res;
	}
}

if (strrchr($_SERVER['SCRIPT_NAME'],'/')==='/ks_antiddos.php')
{ // вызов напрямую из браузера
	print "<h3>ks_antiddos control pannel</h3>";
	$delete_shm = @$_GET['delete'];
	$shm_token = ftok(__FILE__,' ');
	if ($delete_shm)
	{
		print "Deleting shared memory... ";
		$shm_id = shm_attach($shm_token);
		$res = shm_remove($shm_id);
		if ($res) 
			print "Successfull";
		else 
			print "Failed";
	}
	$shm_token_hex = dechex($shm_token);
	print "<br>my shared memory blocks";
	$shms = `ipcs -m`;
	$shms = explode("\n",$shms);
	$header = preg_grep('~key~i',$shms);
	$header = array_values($header);
	$header = $header[0];
	$myshms = preg_grep("~$shm_token_hex~",$shms);
	$anyway = '';
	if (empty($myshms))
	{
		print "<li>not found";
		$anyway = 'anyway';
	}
	$header = preg_split('/[\s\t]+/',$header);
	$header = ' '.implode(' ',$header);
	$header = str_replace(' ','<th>',$header);
	print "<table border=1><thead>$header</thead>\n";
	$myshms = array_values($myshms);
	foreach($myshms as $num=>$line)
	{
	
		$line = preg_split('/[\s\t]+/',$line);
		$shm_id = $line[1];
		$line = ' '.implode(' ',$line);
		$line = str_replace(' ','<td>',$line);
		print "<tr>$line
			</tr>\n";
	}
	print "</table>
		<a href=?delete=1>delete it $anyway</a>";
	$ksa = new ks_antiddos();
	$ksa->auto = false;
	$ksa->doit(1000,1000);
	$res = $ksa->read_iplist();
	if (!$res) 
		print "<br>Cannot read IP list: ".$ksa->error_msg;
	else 
	{
		$count_ips = count($ksa->iplist);
		print "\n<p>&nbsp;</p><li>total $count_ips stored IPs";
		print "\n<table cellspacing=3>";
		foreach($ksa->iplist as $ip=>$times)
		{
			print "\n<tr style='font-family:monospace'><td>$ip<td>".count($times)." hits</tr>";
		}
		print "\n</table>";
		print "Please note that I store no more then  <b>hits_limit</b> hits";
	}
	$ksa->alles();
}


?>
Залил на хостинг - скрипт не хочет никого блокировать, include "$_SERVER[DOCUMENT_ROOT]/path/to/ks_antiddos.php"; я указал правильный путь, ошибок не выскакивает.

Можете посмотреть в чем дело?
 

vitom

Новичок
Сделал тестовый файл:

<?php
shm_attach();
?>

PHP Fatal error: Call to undefined function shm_attach()

Я думаю в этом и проблема, что это означает, как сделать чтобы у меня заработала эта команда, php 5.2
 

vitom

Новичок
'--disable-sysvshm'
это в пхпинфо пишет, это надо врубить как-то наверно
 

c0dex

web.dev 2002-...
Команда форума
Партнер клуба
Переведи на русский язык ошибку, увидишь, что у тебя отсутствует функция, так как она скорей всего не user-defined, идем на сайт php.net и вбимаем ее имя в поиск, видим это:

http://ru2.php.net/manual/en/function.shm-attach.php

Понимаем, что ее может не быть только в случае, если твой php собран без соответствующего модуля, слева в меню есть подсказки про семафоры, там есть пункт про установку:

http://ru2.php.net/manual/en/sem.installation.php

Вывод - надо пересобрать свой php заного с поддержкой --enable-sysvshm

PS: забудь о защите от серьезных DDOS методами php.
 
Сверху