Блокировка спамеров с помощью Eximstats+PF
19.05.2011 - 12:59
Парсер:
и вежливо перезапустим его:
Теперь можно смотреть статистику по Exim в браузере:
Вот дошли руки и до корпоративного сервера - 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
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')
?>
$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"
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>
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]#
/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
58 23 * * * root /eximstats.sh
- Войдите на сайт для отправки комментариев
- Версия для печати
<?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
exim-postgresql-4.76 High performance MTA for Unix systems on the Internet
$content=file_get_contents('http://<мой домен>/eximstats/#Rejected%20ip%20count');
$file = fopen ("/etc/pfacl/pf.spamip","w+");
чтобы не рестартовать pf сделал так:
7 3 * * * /sbin/pfctl -t spamip -T add -f /etc/pfacl/pf.spamip
ну и естественно:
#table <spamip> persist file "/etc/pfacl/pf.spam"
table <spamip> persist
block in log quick from <spamip>
ЗЫ eximstat.sh убрал вообще всё запускаю из крона
если пхп делается из под рута то лучше б он не /etc/pf-mail-spammers правил а в таблицу добовлял их на лету, без перезапуска pf_а
а в файле pfа указать
Кому как удобней, можно й так.
Could not open input file: /scripts/eximstats.php
=(
не совсем ясно где лежит eximstats.php
судя по [root@router /]
из строчки [root@router /]# cat eximstats.php следует что он лежит в корне., это так?
Все приведено для примера, ложите куда хочете.