понедельник, 20 октября 2008 г.

Антибот для серверов cPanel / WHM, FreeBSD

Скрипт читает последние записи из логов апача и банит назойливых роботов фаерволом ipfw
Можно модицировать под линукс (iptables)

Сам код скрипта:




< ?
/*
* antirobot.php
* Скрипт читает последние записи из логов апача и банит назойливых роботов фаирволом ipfw.
* Банит подсеть класса "C" - 256 айпи адресов.
* Перед баном новых разбанивает какойто процент из самых старых забаненных.
* Пускать по крону раз в минуту.
* created by Codemaster
* Права пренадлежат Codemaster
*/

// где лежат логи апача
$config ["http_log_dir"] = "/wwwroot/1managment/data/logs";

// куда писать отчет
$config ["log_fn"] = "/var/log/antirobot.log";

// за какой интервал времени искать роботов в логах
$config ["interval"] = 100;

// какой максимальной длины конец лога читать
$config ["max_log_read_size"] = 100000;

// базовае правило фаирвола
$config ["fw_base_rule"] = 40;

// сколько правил считая от базового использовать (от этого зависит частота разбана)
$config ["fw_no_rules"] = 10;

// сколько запросов за последний интервал времени должен сделать робот чтобы быть замеченным
$config ["min_ban_requests_no"] = 5;

// сколько из них доожны быть html (не css/js/gif/jpg/png/exe)
$config ["min_ban_http_percent"] = 90;

// маски которые не баним
$config ["green_list"] = array (
"66.249.", /*google*/
"66.228.", "74.6.", /*yahoo*/
"65.52.", "65.53.", "65.54.", "65.55.", /*msn*/
);

$t0 = time () - $config ["interval"];
$dh = opendir ($config ["http_log_dir"]);

$cClasses = array ();

while ($fn = readdir ($dh)) {
$ffn = $config ["http_log_dir"] . "/" . $fn;
if (is_file ($ffn) && filectime ($ffn) > $t0) {
$fr = fopen ($ffn, "r");

$fs = filesize ($ffn);
if ($fs > $config ["max_log_read_size"]) {
fseek ($fr, $fs - $config ["max_log_read_size"], SEEK_SET);
}

while (!feof ($fr)) {
$s = fgets ($fr);

if (preg_match ("|(d+.d+.d+.d+)[^[]+[([^]]+)]|", $s, $ar)) {
$ip = $ar [1];
$wh = strtotime ($ar [2]);

if ($wh > $t0) {
$a2 = explode (".", $ip);
$cClass = join (".", array_slice ($a2, 0, 3));

$cClasses [$cClass] ["hit"] ++;

$a = explode (""", $s);
$cClasses [$cClass] ["ua"] = $a [count ($a) - 2];

if (strstr ($s, ".jpg ") || strstr ($s, ".gif ") || strstr ($s, ".png ") || strstr ($s, ".css ") || strstr ($s, ".js ")|| strstr ($s, ".exe ")) {
$cClasses [$cClass] ["img"] ++;
}
}
}
}
fclose ($fr);
}
}
closedir ($dh);

$thisRuleNo = $config ["fw_base_rule"] + floor (time () / 60) % $config ["fw_no_rules"];

$cmd = "ipfw delete $thisRuleNo 2>/dev/null";
`$cmd`;

foreach ($cClasses as $cClass => $cInfo) {
if ($cInfo ["hit"] >= $config ["min_ban_requests_no"]) {

$nImg = (int) $cInfo ["img"];
$nHtml = $cInfo ["hit"] - $nImg;
$percentHtml = $nHtml / $cInfo ["hit"] * 100;
if ($percentHtml > $config ["min_ban_http_percent"]) {

$isGreen = false;
foreach ($config ["green_list"] as $i) {
if (strstr ($cClass, $i)) {
$isGreen = true;
}
}

if (!$isGreen) {
$cmd = "ipfw add $thisRuleNo deny ip from $cClass.0/24 to me 80";
`$cmd`;

$s = date ("r") . "t" . $cInfo ["hit"] . "t" . $nImg . "t" . $cClass . ".0/24t" . $cInfo ["ua"] . "n";
$fw = fopen ($config ["log_fn"], "a");
fputs ($fw, $s);
fclose ($fw);
}
}
}
}
?>


[ad#ad-5]

Комментариев нет:

Отправить комментарий