The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]

Автоматизация борьбы со спамботами в своей сети
Администраторы больших сетей регулярно получают жалобы на исходящий из них спам. Получив жалобу, 
можно найти виновного и устранить проблему. Но нехорошо узнавать о таких делах
только от чужих людей.
Спамеров вполне можно вычислить самому, и принять меры раньше, чем кто-то пострадает.

Чисто интуитивно достаточно запустить tcpdump на исходящем канале, и
посмотреть, какие IP-адреса больше в
сего посылают SYN-пакетов на 25 порт.

  tcpdump -ni bridge0 'tcp[tcpflags] & tcp-syn != 0 and dst port 25'

В идеале это был бы ваш SMTP-сервер. В действительности вы увидите в основном
IP-адреса простых пользователей,
"одержимых бесами". Дело в том, что обычный спамбот создает SMTP-соединений во много раз больше 
вашего почтового сервера. Причем с разными IP-адресами.

В наши дни все нормальные почтовые сервера имеют PTR-запись DNS. Простые клиенты, напротив, 
такой записи обычно не имеют. Если почтовый сервер может устанавливать SMTP-соединения 
со множеством IP-адресов, то для простого клиента эта величина обычно не более 1-2 (например, 
пользование удаленными SMTP-серверами с лаптопа).

Исходя из этого, можно автоматически определять спамботов в нашей сети, и
блокировать их (например,
средствами IPFW). В качестве критерия оценки мы установили максимальное количество IP-адресов, 
с которыми каждый хост может общаться по SMTP в течение 5 минут. Для хостов с
реверсной записью DNS это 200,
для хостов без реверсной записи - 20. Если хост превышает этот лимит, он
попадает в черный список на сутки.

Нами написан Perl-скрипт, запускающий tcpdump на 5 минут, и анализирующий результаты. 
Хосты-нарушители заносятся в таблицу PostgreSQL для удобства персонала, и затем помещаются 
в таблицу IPFW. Правила файрвола блокируют все соединения на 25 порт с хостов,
находящихся в данной таблице.

Текст скрипта:

       #!/usr/local/bin/perl
       # dimss@stalin.lv 2009-08-20

       my $colltime = 300;    # How long to collect data
       my $rev_limit = 200;   # Remote IP limit for hosts with PTR record
       my $norev_limit = 20;  # Remote IP limit for hosts without PTR record
       my $table_no = 1; # Number of IPFW table

       use strict;
       use warnings;

       use POSIX ':signal_h';
       use Socket;
       use DBI;

       #
       # Collect data
       # Run tcpdump for some time
       #

       my $conns = {};

       my $mask = POSIX::SigSet->new( SIGALRM );
       my $action = POSIX::SigAction->new(
               sub {
                       system("killall tcpdump");
               },
               $mask
       );
       my $oldaction = POSIX::SigAction->new();
       sigaction(14, $action, $oldaction);

       alarm($colltime); # Run tcpdump for this amount of time
       open(T, "/usr/sbin/tcpdump -ni bridge0 'tcp[tcpflags] & tcp-syn != 0 " .
                       "and dst port 25' " .
                       "2>/dev/null |") or die;

       while(<T>){
               /\ ((\d+\.){3}\d+).+?((\d+\.){3}\d+)/;
               my $locip = $1;
               my $remip = $3;
               #print "$locip $remip\n";
               $conns->{$locip} ||= {};
               $conns->{$locip}->{$remip} ||= 1;
       }
       alarm(0);
       sleep(1);

       #
       # Analyze connections
       #


       $mask = POSIX::SigSet->new( SIGALRM );
       $action = POSIX::SigAction->new(
               sub {
                       die("Reverse lookup took too long");
               },
               $mask
       );
       $oldaction = POSIX::SigAction->new();
       sigaction(14, $action, $oldaction);

       alarm(60); # Reverse DNS lookups must complete within this period

       my %concount;
       my %bots;

       for my $locip (keys(%$conns)){
               #print("Loc IP: $locip\n");
               my $cnt = 0;
               for my $remip (keys(%{$conns->{$locip}})){
                       #print("  Rem IP: $remip\n");
                       $cnt++;
               }
               $concount{$locip} = $cnt;
       }

       for my $locip (sort {$concount{$b} <=> $concount{$a}} keys(%concount)){
               if($concount{$locip} > $norev_limit){
                       my $ip = inet_aton($locip);
                       my $name = gethostbyaddr($ip, AF_INET);
                       if($concount{$locip} > ($name ? $rev_limit : $norev_limit)){
                               #print("$locip: $concount{$locip} (" . ($name || '') . ")\n");
                               $bots{$locip} = $name;
                       }
               }
       }

       alarm(0);

       #
       # Update database
       #

       $mask = POSIX::SigSet->new( SIGALRM );
       $action = POSIX::SigAction->new(
               sub {
                       die("Database timeout");
               },
               $mask
       );
       $oldaction = POSIX::SigAction->new();
       sigaction(14, $action, $oldaction);

       alarm(15);

       my $dbh = DBI->connect("dbi:Pg:host=db.host.tld;dbname=spambot",
               "spambot", "passwd");
       if(!$dbh) {
               die("Cannot connect to DB");
       }

       my $query;
       my $sth;
       my $rv;
       for my $botip (keys(%bots)){
               #print "$botip\n";
               my $qname = $dbh->quote($bots{$botip});
               $query = "
                       update spambot_hosts set
                               active_till = now() + '1 days',
                               hostname = $qname
                       where ip = '$botip'
               ";
               $sth = $dbh->prepare($query);
               $rv = $sth->execute();
               if($rv != 1){
                       $query = "
                               insert into spambot_hosts
                               (ip, hostname, active_till)
                               values
                               ('$botip', $qname, now() + '1 days')
                       ";
                       $sth = $dbh->prepare($query);
                       $sth->execute();
               }
       }
       $query = "
               delete from spambot_hosts
               where active_till < now()
       ";
       $sth = $dbh->prepare($query);
       $sth->execute();

       #
       # Get full list of banned hosts from DB
       #

       $query = "
               select ip from spambot_hosts
       ";
       $sth = $dbh->prepare($query);
       $sth->execute();

       my %dlist;
       while(my $row = $sth->fetchrow_hashref){
               $dlist{$row->{ip}} = 1;
       }

       undef $dbh;
       alarm(0);

       #
       # Read list of banned hosts from kernel (ipfw) table
       #

       my %klist;
       if(open(KTABLE, "/sbin/ipfw table $table_no list|")){
               while(<KTABLE>){
                       chomp();
                       s/\/32//;
                       my ($prefix, $queue) = split();
                       $klist{$prefix} = 1;
               }
               close(KTABLE);
       }

       #
       # Update kernel table
       #

       for my $host (keys(%dlist)){
               unless($klist{$host}){
                       #print "Add $host\n";
                       system("/sbin/ipfw table $table_no add $host");
               }
       }

       for my $host (keys(%klist)){
               unless($dlist{$host}){
                       #print "Remove $host\n";
                       system("/sbin/ipfw table $table_no delete $host");
               }
       }

       exit;

Из /etc/ipfw.rules:

   #....
   ipfw -q add deny tcp from "table(1)" to any 25
   #....

У нас скрипт работает на шейпере, обслуживающем только заграничный канал.
Местный трафик им не анализируется
и не блокируется. При этом большая часть "хорошей" почты ходит именно по
местным каналам, но спамеры
спамят в основном по заграничному каналу. Так что лимиты вам наверняка придется
подстроить под себя.
Возможно, вам придется также реализовать "белый список", если у вас есть очень
активные SMTP-сервера.

На момент написания статьи в "расстрельном списке" несколько десятков хостов.
Жалоб за истекшие сутки
не поступало, хотя раньше их было множество.
 
24.08.2009 , Автор: Дмитрий Иванов
Ключи: spam, virus, mail, filter / Лицензия: CC-BY
Раздел:    Корень / Администратору / Сетевые сервисы / Mail, почта / Борьба со спамом, фильтрация почты

Обсуждение [ Линейный режим | Показать все | RSS ]
  • 1.1, Аноним (-), 11:29, 24/08/2009 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    фильтр PF в FreeBSD\OpenBSD умеет самостоятельно вылавливать адреса, превышающие порог на частоту соединений и заносить их в свою внутреннюю таблицу. По этой таблице можно и блокировать трафик, и вылавливать нарушителей. Все гораздо проще и изящнее ...
     
     
  • 2.2, Банзай (??), 11:38, 24/08/2009 [^] [^^] [^^^] [ответить]  
  • +/
    >фильтр PF в FreeBSD\OpenBSD умеет самостоятельно вылавливать адреса, превышающие порог на частоту
    >соединений и заносить их в свою внутреннюю таблицу. По этой таблице
    >можно и блокировать трафик, и вылавливать нарушителей. Все гораздо проще и
    >изящнее ...

    Не умеет.


     
     
  • 3.6, Аноним (-), 13:51, 24/08/2009 [^] [^^] [^^^] [ответить]  
  • +/
    Умеет, конечно.
     
     
  • 4.9, Щекн Итрч (ok), 02:37, 25/08/2009 [^] [^^] [^^^] [ответить]  
  • +/
    >Умеет, конечно.

    Попробуйте и доложите.
    Желательно с дешифрованными tpcdump'ом логами, иллюструющими ваш набор правил.

     
     
  • 5.14, ws (ok), 11:57, 25/08/2009 [^] [^^] [^^^] [ответить]  
  • +/
    Где-то так:
    table <smtp_bruteforce> persist
    block drop in quick from <smtp_bruteforce>
    pass in quick proto tcp from <local_net> to any port smtp flags S/S keep state \
      (max-src-conn-rate 20/300, overload <smtp_bruteforce> flush global)

    Теперь в таблице <smtp_bruteforce> будет содержаться забаненые ip.

    Очистку этой таблицы можно производить через запуск по крону программы, очищающая устаревшие записи на сутки:
    /usr/local/sbin/expiretable -t 79200 smtp_bruteforce

     
     
  • 6.23, pavlinux (ok), 20:11, 25/08/2009 [^] [^^] [^^^] [ответить]  
  • +/
    А где ключевые слова "умеет самостоятельно"?

     
  • 6.26, Щекн Итрч (ok), 00:04, 26/08/2009 [^] [^^] [^^^] [ответить]  
  • +/
    "Где-то" или "есть логи, иллюстрирующие гипотезу"?
    Можно фрагмент лога?
     
     
  • 7.30, ws (ok), 10:22, 26/08/2009 [^] [^^] [^^^] [ответить]  
  • +/
    У меня большой сети зомбируемых машин нет. Поэтому оставлю вам это на самопроработку.

    В этом коде, конечно не учтено:
    >>Здесь дело не в количестве соединений, а в количестве IP-адресов, с которыми устанавливается соединение.

    но тем немение, работает с частотой создаваемых соединений.

    ps: такая связка успешно функционирует у меня на блокирование попыток подключения по ssh.

     
     
  • 8.32, настоящий_аноним (?), 15:39, 26/08/2009 [^] [^^] [^^^] [ответить]  
  • +/
    Мой друг, это же классика Про max-src-conn-rate pf hashlimit iptables знает... текст свёрнут, показать
     
     
  • 9.35, настоящий_аноним (?), 15:47, 26/08/2009 [^] [^^] [^^^] [ответить]  
  • +/
    Причем таймаут хранится для каждой записи отдельно ... текст свёрнут, показать
     
  • 9.37, ws (ok), 16:46, 26/08/2009 [^] [^^] [^^^] [ответить]  
  • +/
    Естественно И применимая в текущей задаче Так и в pf таймауты в таблице выс... текст свёрнут, показать
     
     
  • 10.39, аноним (?), 01:03, 27/08/2009 [^] [^^] [^^^] [ответить]  
  • +/
    Если уж быть строгим и занудным до конца, то и iptables, и ipset - это всего лиш... текст свёрнут, показать
     
  • 2.3, Дима Иванов (?), 12:21, 24/08/2009 [^] [^^] [^^^] [ответить]  
  • +/
    Здесь дело не в количестве соединений, а в количестве IP-адресов, с которыми устанавливается соединение. К тому же, нужна гибкая политика, кого и как банить.
     

  • 1.4, Andrew (??), 12:43, 24/08/2009 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    Это, конечно, от ситуации зависит, но проще просто ЗАКРЫТЬ весь исходящий траффик на 25й порт, и проковырять его только для реальных почтовых серваков.

    Логика очень простая: кому действительно надо иметь выход на 25й порт, осознанно попросят его открыть, но их будет очень мало. Всем остальным это не надо, и они будут закрыты => боты обломаются. При этом надо, разумеется, _документировать_ эту политику.

     
     
  • 2.5, Дима Иванов (?), 12:45, 24/08/2009 [^] [^^] [^^^] [ответить]  
  • +/
    Да, так было бы лучше всего. Но пользователям этого не объяснить. Т.е. увеличится число тупых кейсов у саппорта. А так заодно выявляем сифозные хосты в сети.
     
     
  • 3.21, mr_gfd (?), 15:06, 25/08/2009 [^] [^^] [^^^] [ответить]  
  • +/
    >Да, так было бы лучше всего. Но пользователям этого не объяснить. Т.е.
    >увеличится число тупых кейсов у саппорта. А так заодно выявляем сифозные
    >хосты в сети.

    На трипаки в сетке похер, а закрытый на выход 25й порт - это айс. парсить maillog - изящнее и информативнее.

     

  • 1.7, jordan (?), 22:19, 24/08/2009 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    А есть чтото подобное для сервиса icq?
     
  • 1.8, настоящий_аноним (?), 00:59, 25/08/2009 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    Это же надо так мучаться... В iptables это делается несколькими строчками:
    # Создаем список спамеров
    ipset -N spambots iphash
    # Блокируем спамеров
    iptables -I FORWARD -m set --set spambots src -j DROP
    # Если кто-то превышает лимит подключений - заносим в "черный список"
    iptables -A FORWARD -p tcp --dport 25 -m state --state NEW -m hashlimit --hashlimit-name spamcheck --hashlimit-mode srcip --hashlimit-above 20/min -j SET --add-set spambots src
    # Еще можно добавить проверку на количество одновременных соединений с одного адреса
    iptables -A FORWARD -p tcp --dport 25 -m state --state NEW -m connlimit --connlimit-above 10 -j SET --add-set spambots src

    Вуаля! Не более 20 новых соединений в минуту, не более 10 соединений одновременно.
    Правда, hashlimit жестко задает контролируемые периоды времени (минута, час, сутки). Если хотите задавать их произвольно - см. recent.

    И не жалуйтесь, что "для этого надо патчить ядро и т.п.". Это всего лишь следствие неправильного выбора дистрибутива =) В debian stable (с iptables и xtables-addons из testing) все работает "искаропки".

     
     
  • 2.24, andrew (??), 20:29, 25/08/2009 [^] [^^] [^^^] [ответить]  
  • +/
    Нда. Скрипт на двести строчек... и три-четыре строчки на iptables и pf.
    Наглядно понимаешь разницу между сисадмином и велосипедистом.
     
     
  • 3.27, Щекн Итрч (ok), 00:05, 26/08/2009 [^] [^^] [^^^] [ответить]  
  • +/
    >Нда. Скрипт на двести строчек... и три-четыре строчки на iptables и pf.
    >
    >Наглядно понимаешь разницу между сисадмином и велосипедистом.

    НЕ работают "три-четыре строчки на iptables и pf". НЕ работают.
    Бабушку свою жить поучите.

     
     
  • 4.31, аноним (?), 11:02, 26/08/2009 [^] [^^] [^^^] [ответить]  
  • +/
    А у меня - работают. Причем далеко не на одном сервере.
    Вопрос: у кого из нас двоих руки из плеч, а у кого из ...?
     
  • 4.33, настоящий_аноним (?), 15:44, 26/08/2009 [^] [^^] [^^^] [ответить]  
  • +/
    >НЕ работают "три-четыре строчки на iptables и pf". НЕ работают.

    Полагаю, проблема не у "iptables и pf", а у вас. Где-то в области /dev/hands либо /dev/brain. Возможно, обусловлено ошибками при сборке ДНК :)

     

  • 1.10, shadow_alone (ok), 04:52, 25/08/2009 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    Самое простое
    -A FORWARD -p tcp --dport 25 -j LOG --log-prefix smtpport:
    включить logwatch и получать почту с логом ежедневно, не гнушаясь просматривать.
     
  • 1.11, .snake (?), 05:12, 25/08/2009 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    -A FORWARD -s 192.168.0.0/16 -p tcp -m tcp --dport 25 -m state --state NEW -m recent --set --name SMTP
    -A FORWARD -s 192.168.0.0/16 -p tcp -m tcp --dport 25 -m state --state NEW -m recent --update --seconds 60 --hitcount 5 --name SMTP -j REJECT --reject-with icmp-port-unreachable

    Автоматически блокирует рассылку спама от клиентов. Как только спам прекращается почта начинает работать :)

     
     
  • 2.12, shadow_alone (ok), 05:21, 25/08/2009 [^] [^^] [^^^] [ответить]  
  • +/
    >-A FORWARD -s 192.168.0.0/16 -p tcp -m tcp --dport 25 -m state
    >--state NEW -m recent --set --name SMTP
    >-A FORWARD -s 192.168.0.0/16 -p tcp -m tcp --dport 25 -m state
    >--state NEW -m recent --update --seconds 60 --hitcount 5 --name SMTP
    >-j REJECT --reject-with icmp-port-unreachable
    >
    >Автоматически блокирует рассылку спама от клиентов. Как только спам прекращается почта начинает
    >работать :)

    очень интересно, из-за кого-то одного будут страдать все - это во первых.
    Во вторых, при /16 вполне возможно одновременное подключение более 5 клиентов в минуту, так что, думаю , не лучший вариант.

     
     
  • 3.13, .snake (?), 06:23, 25/08/2009 [^] [^^] [^^^] [ответить]  
  • +/
    Страдать будет только тот кто спамит, проверено.
    Префикс /16 указан для примера, роли это не влияет
     
  • 3.16, настоящий_аноним (?), 13:11, 25/08/2009 [^] [^^] [^^^] [ответить]  
  • +/
    >очень интересно, из-за кого-то одного будут страдать все - это во первых.
    >Во вторых, при /16 вполне возможно одновременное подключение более 5 клиентов в минуту, так что, думаю , не лучший вариант.

    Мсье самый умный? Мсье никогда не читает документацию?
    Шагом марш читать man iptables!
    recent хранит информацию по каждому айпишнику отдельно. /16 задает только "область наблюдения".

     
     
  • 4.17, shadow_alone (ok), 13:16, 25/08/2009 [^] [^^] [^^^] [ответить]  
  • +/
    >>очень интересно, из-за кого-то одного будут страдать все - это во первых.
    >>Во вторых, при /16 вполне возможно одновременное подключение более 5 клиентов в минуту, так что, думаю , не лучший вариант.
    >
    >Мсье самый умный? Мсье никогда не читает документацию?
    >Шагом марш читать man iptables!
    >recent хранит информацию по каждому айпишнику отдельно. /16 задает только "область наблюдения".
    >

    Мсье не страдает такой хренью, ибо.....

     
     
  • 5.18, настоящий_аноним (?), 14:05, 25/08/2009 [^] [^^] [^^^] [ответить]  
  • +/
    >Мсье не страдает такой хренью, ибо.....

    Ибо считает, что лучше написать двадцать тормозных велосипедов по сто килобайт каждый, чем один раз прочитать документацию по штатным возможностям своей системы.
    Я правильно вас понял?

     
     
  • 6.19, shadow_alone (ok), 14:18, 25/08/2009 [^] [^^] [^^^] [ответить]  
  • +/
    совершенно неправильно....
    сплошной, блин, офф топ.... (лучше по русски - не по теме)
    далек от таких ньюансов.... мелко.
    ну судите строго.
    не видел такого в 1.2
    а дальше уже, как то, не очень вставляет - железо лучше, да и оно уже прошлое.

     

  • 1.15, emp (??), 12:11, 25/08/2009 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    за прогу - зачёт. за ночь наловила 87 хостов. фикусы с iptables стоят на релее. но вот на исходящий поток от клиентов надо ставить чтото заносящее инфу в биллинг. чтоб тп по ночам спокойно могло удалить/приостановить бан клиенту, а не ждать админа чтобы он посмотрел в табличку.
     
     
  • 2.22, Дима Иванов (?), 15:17, 25/08/2009 [^] [^^] [^^^] [ответить]  
  • +/
    >надо ставить чтото заносящее инфу в биллинг. чтоб тп по ночам спокойно могло >удалить/приостановить бан клиенту, а не ждать админа чтобы он посмотрел в табличку.

    Именно!!! Наконец кто-то понял мою задумку :)

     

  • 1.20, maap (?), 14:44, 25/08/2009 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    Я бы предложил анализировать коннтраки с ASSURED на 25 порту.
     
     
  • 2.36, настоящий_аноним (?), 15:52, 26/08/2009 [^] [^^] [^^^] [ответить]  
  • +/
    >Я бы предложил анализировать коннтраки с ASSURED на 25 порту.

    Кстати вопрос: ctstatus анализирует все подключения или только related по conntrack?

     

  • 1.25, admin (??), 23:04, 25/08/2009 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    многабукаф в перле. может и красиво, но оч тяжело.
    у меня на шеле в 5 строк влезло.
     
     
  • 2.28, Щекн Итрч (ok), 00:06, 26/08/2009 [^] [^^] [^^^] [ответить]  
  • +/
    >многабукаф в перле. может и красиво, но оч тяжело.
    >у меня на шеле в 5 строк влезло.

    И не слабО их здесь привести?
    Что-то мешает? Шарики?

     
  • 2.34, настоящий_аноним (?), 15:46, 26/08/2009 [^] [^^] [^^^] [ответить]  
  • +/
    >у меня на шеле в 5 строк влезло.

    У меня на iptables 3-4. У товарища выше на pf - 3. Что вы там так длинно пишете? ;)

     

  • 1.38, XoRe (ok), 00:25, 27/08/2009 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    Скрипт, думаю, будет полезен.
    Он хорошо подходит, когда нужно оповещать пользователя о том, что с него сыплется спам.

    Могу посоветовать прикрутить к нему отправлялку писем пользователям.
    Типа "Это автоматическое сообщение - у вас на компе вирус. Можете скачать антивирус с нашего фтп (ссылка), обновить его бесплатно с нашего фтп (ссылка)."
    Ещё можно ссылку на пошаговое описание, как что делать.
    А описание в картинках)
    Думаю, это может ещё больше уменьшить звонки в суппорт.

    Ещё могу посоветовать анализировать dns запросы типа MX - они тоже обычно генерятся именно спамописателями.
    Вылавливать такие запросы тоже можно с помощью tcpdump.

    Ещё в свое время заметил, что размер "окна" (параметр такой в ip или tcp заголовке) у спамописем равен 24000.
    Помнится, даже после долгого наблюдения не заметил ничего другого, кроме спама, с таким окном.
    Но это уже не так однозначно.

    А ещё могу посоветовать:
    ipfw add 1 skipto 4 tcp from table(x) to not me 25
    ipfw add 2 skipto 4 tcp from any to not me 25 limit src-addr 10
    ipfw add 3 deny tcp from any to not me 25

    Просто не дает устанавливать больше 10 одновременных соединений)
    Правило с limit - динамическое.
    Параметры динамических правил можно настроить тут:
    sysctl net.inet.ip.fw

    А в table(x) кидать "официальных спаммеров")
    Т.е. тех, кого не надо блочить.

    Можно пойти более хитро)
    Можно воспользоваться подсистемой netgraph - связать модуль для bpf и модуль для netflow.
    И настроить так, чтобы получать статистику netflow о спаммерах.
    А netflow уже хоть куда - хоть в БД, хоть в html)

     
  • 1.40, Илья Евсеев (?), 11:32, 03/09/2009 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    То же самое, только чуть короче :)
    http://sources.homelink.ru/spamblock/
     
  • 1.41, Kost (?), 15:53, 16/01/2012 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    Время записи в журнал client_connection_status_update_time 5m Задаём промеж... большой текст свёрнут, показать
     


     Добавить комментарий
    Имя:
    E-Mail:
    Заголовок:
    Текст:




    Партнёры:
    PostgresPro
    Inferno Solutions
    Hosting by Hoster.ru
    Хостинг:

    Закладки на сайте
    Проследить за страницей
    Created 1996-2024 by Maxim Chirkov
    Добавить, Поддержать, Вебмастеру