Блокировка спамеров с помощью Eximstats+PF

19.05.2011 - 12:59

Вот дошли руки и до корпоративного сервера - Exim. Посмотрев статистику с помощью встроенного парсера логов(eximstats), решил банить спаммеров по IP без раздумывания.
Напишем скрипт, который будет запускать eximstats с необходимы опциями, парсить html-лог и складывать в файл "/etc/pf-mail-spammers" нежелательные IP, которые в качестве таблицы будут подгружаться в PF:

[root@router /]#cat eximstats.sh
/usr/local/sbin/eximstats -nt -nr -include_original_destination -chartdir /usr/local/www/eximstats/ -html=/usr/local/www/eximstats/ \ eximstats.html /var/log/exim/main
sleep 5
/usr/local/bin/php /eximstats.php
sleep 5
pfctl -f /etc/pf.sh

Парсер:
[root@router /]# cat eximstats.php
<?php                                                                                                                                                        
$content=file_get_contents('http://<ваш домен>/eximstats/#Rejected');    
$pos = strpos($content,'<h2>Top 50 rejected ips by message count</h2>');
$content = substr($content, $pos);
$pos = strpos($content, '<hr>');
$content = substr($content, 0, $pos);
preg_match_all('/\d*\.\d*\.\d*\.\d*/', $content, $output);
foreach($output as $index => $val)
{  
foreach($val as $val2)
{
if ((substr($val2, 0, 3)!='127')and(substr($val2, 0, 7)!='192.168'))
{  
$mass[]=$val2;
}
}
}
 $str = implode("\n", $mass);
 $file = fopen ("/etc/pf-mail-spammers","w+");
 fputs ( $file, $str);
 fclose ($file);
 echo ('ok')
?>  

Добавим таблицу и блокирующее правило в /etc/pf.conf:

#Спамеры живут тут.
table <mailspam> persist file "/etc/pf-mail-spammers"
block in log quick from <mailspam>

Для просмотра лога eximstats, создадим каталог для местонахождения лога и добавим директорию в Apache:

[root@router /# mkdir /usr/local/www/eximstats
<Directory /usr/local/www/eximstats>
    DirectoryIndex eximstats.html
    AllowOverride None
    Order deny,allow
    Allow from <IP>
</Directory>

и вежливо перезапустим его:
[root@router /usr/local/etc/rc.d]# apachectl graceful
/usr/local/sbin/apachectl graceful: httpd gracefully restarted
[root@router /usr/local/etc/rc.d]#

Теперь можно смотреть статистику по Exim в браузере:
http://<ваш домен>/eximstats/

Добавим в крон для выполнения по расписанию:

[root@router /etc]# cat /etc/crontab | grep eximstats
#eximstats
58 23 * * * root /eximstats.sh

Ваша оценка: Нет Средняя: 2 (4 голосов)

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


<?php
$content=file_get_contents('http://ваш сервер/eximstats/');
$pos = strpos($content,'Top 50 rejected ips by message count');
$content = substr($content, $pos);
$pos = strpos($content, '');
preg_match_all('/\d*\.\d*\.\d*\.\d*/', $content, $output);
foreach($output as $val)
{
foreach($val as $val2)
{
if ((substr($val2, 0, 3)!='127')and(substr($val2, 0, 7)!='192.168'))
{
$mass[]=$val2;
}
}
}
if (isset($mass))
{
$str = implode("\n", $mass);
$file = fopen ("/etc/pf-mail-spammers","w+");
fputs ( $file, $str);
fclose ($file);
}
?>



Не работает ваш код.
Warning: implode(): Invalid arguments passed in /eximstats.php on line 18

Методом тыка мне показалось что не объявлен массив, после его объявления ошибок нет, но файл пуст.



<?php
$content=file_get_contents('http://ваш сервер/eximstats/');
$pos = strpos($content,'Top 50 rejected ips by message count');
$content = substr($content, $pos);
$pos = strpos($content, '');
preg_match_all('/\d*\.\d*\.\d*\.\d*/', $content, $output);
foreach($output as $val)
{
foreach($val as $val2)
{
if ((substr($val2, 0, 3)!='127')and(substr($val2, 0, 7)!='192.168'))
{
$mass[]=$val2;
}
}
}
if (isset($mass))
{
$str = implode("\n", $mass);
$file = fopen ("/etc/pf-mail-spammers","w+");
fputs ( $file, $str);
fclose ($file);
}
?>



Получилось поправить?



надо поправить eximstat.php если версия eximа 4.7

pkg_info|grep exim
exim-postgresql-4.76 High performance MTA for Unix systems on the Internet

grep exim /scripts/eximstat.php
$content=file_get_contents('http://<мой домен>/eximstats/#Rejected%20ip%20count');

grep spamip /scripts/eximstat.php
 $file = fopen ("/etc/pfacl/pf.spamip","w+");

чтобы не рестартовать pf сделал так:
4      3       *       *       *       /sbin/pfctl -t spamip -T expire 86400
7      3       *       *       *       /sbin/pfctl -t spamip -T add -f /etc/pfacl/pf.spamip

ну и естественно:
grep spamip /etc/pf.conf
#table <spamip> persist file "/etc/pfacl/pf.spam"
table <spamip> persist
block in log quick from <spamip>

ЗЫ eximstat.sh убрал вообще всё запускаю из крона



если пхп делается из под рута то лучше б он не /etc/pf-mail-spammers правил а в таблицу добовлял их на лету, без перезапуска pf_а

pfctl -t mailspam -T add <ип спамера>

а в файле pfа указать
table <mailspam> persist

Happy



Кому как удобней, можно й так.Winking



-charts option not specified. Use -help for help.
Could not open input file: /scripts/eximstats.php

=(



не совсем ясно где лежит eximstats.php
судя по [root@router /]
из строчки [root@router /]# cat eximstats.php следует что он лежит в корне., это так? Happy



Все приведено для примера, ложите куда хочете. Winking