Вход:  Пароль:  
FreeSource: OnyX/Postfix?/none1 ...
Free Source | Каталог | Изменения | НовыеКомментарии | Пользователи | Регистрация |
Это старая версия OnyX/Postfix/none1 за 2007-11-12 12:59:23..
Зачем: Использование техники greylisting с помошью postgrey является очень мощным оружием против спама. В процессе работы программа хранит и обрабатывет промежуточные данные в файле базы данных Berkeley DB. Со временем эта база разрастается и может содержать до мескольких десятков и даже сотен мегабайт. В составе дистрибутива postgrey нет утилиты для менеджмента этой базы, контроллировать её не представляется возможным. Дело в том, что в ней хранятся записи о бывших и существующих сессиях smtp и никуда не удаляются, только прибавляя в размере файлу базы данных. Однако в большинстве случаев в этой базе можно найти некоторое количество записей (напимер множество хостов домена *.domain.com), которые гораздо легче обработать другим ОБЩИМ способом, таким как, например, отказ всем хостам, содержащим в своём имени *.domain.com при помощи правил smtpd_*_restrictions. После этого такие записи из базы можно будет удалить. Таким образом мы снизим размер базы данных и время на работу с ней.
Как: Скриптом, который поможет «зачистить» базу postgrey, уменьшит её размер, ускорит работу.
Коментарии: Скрипт использует Socket и BerkeleyDB. С первым модулем проблем не бывает, а вот второй придётся поставить (учитывая все его зависимости). Остальные каменты смотрите в самом скрипте.
Приступим:

#!/usr/bin/perl -w

use strict;
use warnings;
my ($awc_show,$awc_delete);

# функция разрешающая ip хоста в имя хоста
sub resolv($)
{       #IP-HOST
        my $h1 = shift;
        my $iaddr = inet_aton($h1);
        my @h2=gethostbyaddr($iaddr,2);
        if (defined($h2[0]))
        {
                return($h2[0]);
        }
        else
        {
                return("unknown");
        }
}

# функция разрешающая имя хоста в ip хоста
sub r_resolv($)
{       #HOST-IP
        my $name = shift;
        return inet_ntoa(inet_aton($name)) or die "Cant resolv $name!\n";
}

# проверяем аргументы перед началом работы и если их не 2 или не 4 то выводим Usage
if (@ARGV != 2 and @ARGV != 4)
{
        print("Usage: pg_manage [options]
[options]
-s      show hosts with:
        -s N                    N mails received;
        -s spamdomain.com       spamdomain.com and subdomains hosts entrys both;
-d      delete hosts with:
        -d N                    N mails received;
        -d spamdomain.com       spamdomain.com host entry only;
        -d *spamdomain.com      spamdomain.com and subdomains hosts entrys both;
        \n");
        exit(1);
}
# иначе разбираем введённые аргументы
else
{
        if ($ARGV[0] eq "-s")
        {
                $awc_show=lc($ARGV[1]);
        }
        elsif ($ARGV[0] eq "-d")
        {
                $awc_delete=lc($ARGV[1]);
        }
        if (@ARGV == 4)
        {
                if ($ARGV[2] eq "-s")
                {
                        $awc_show=lc($ARGV[3]);
                }
                elsif ($ARGV[2] eq "-d")
                {
                        $awc_delete=lc($ARGV[3]);
                }
        }
}

# подключаем модули
use BerkeleyDB;
use Socket;

# инициализируем работу с БД
# тут надо внимательно, ибо лучше пробовать использовать программу сначала на копии базы данных, а потом на живой базе
# поэтому исправляем параметр -Filename чуть ниже на актуальный
tie(my %h, "BerkeleyDB::Btree",
        -Filename => "/var/db/postgrey/postgrey_clients.db",
#       -Filename => "/tmp/postgrey_clients2.db",
        )
        or die "ERROR: can't open  database $ARGV[0]: $!\n";

# Ну а дальше пошла  сама программа.
while (my ($key, $value) = each %h)
{
        my ($c,$l) = split(/,/,$value);

        if (defined($awc_show))
        {
                if ($awc_show!~m|[^0-9]| and $awc_show <= $c)
                {
                        my $host = resolv($key);
                        print("$host\[$key\]\t\t$c\n");
                }
                elsif ($awc_show=~m|[^0-9]|)
                {
                        my $host=resolv($key);
                        if ($host=~m|$awc_show|)
                        {
                                print("$host\[$key\]\t\t$c\n");
                        }
                }
        }
        if (defined($awc_delete))
        {
                if ($awc_delete=~m|^\*[0-9a-z].+| and $awc_delete!~m|\*\.| and $awc_delete!~m|\.\*|)
                {
                        $awc_delete=reverse($awc_delete);
                        my $tail=chop($awc_delete);
                        $awc_delete=reverse($awc_delete);
                        my $tmp1=resolv($key);
                        if ($tmp1=~m|$awc_delete|)
                        {
                                delete $h{$key};
                                print("deleting $tmp1\n");
                        }
                        $awc_delete=reverse($awc_delete);
                        $awc_delete.=$tail;
                        $awc_delete=reverse($awc_delete);
                }
                elsif ($awc_delete=~m|^[0-9]+$|)
                {
                        if ($c >= $awc_delete)
                        {
                               print("deleting $key with $c mails, min is $awc_delete\n");
                               delete $h{$key};
                        }
                }
                elsif ($awc_delete=~m|^[0-9a-z]|  and $awc_delete!~m|\*\.| and $awc_delete!~m|\.\*|)
                {
                        my $tmp1=r_resolv($awc_delete);
                        if ($tmp1 eq $key)
                        {
                                delete $h{$key};
                                print("deleting $tmp1\n");
                        }
                }
                else {die "Invalid -d option\n"}
        }
}

untie %h;

exit(0);


Каменты приветствуются!


 
Файлов нет. [Показать файлы/форму]
Комментариев нет. [Показать комментарии/форму]