UNIX FORUM
09 September 2010, 21:15:23 *
Welcome, Guest. Please login or register.
Did you miss your activation email?

Login with username, password and session length
News: SMF форум только что установлен!
 
   Home   Help Login Register  
Pages: [1]
  Print  
Author Topic: скрипт блокировки спамеров на www средствами ipfw table и nginx  (Read 1040 times)
0 Members and 1 Guest are viewing this topic.
admin
Администратор
Ветеран
*****
Offline Offline

Posts: 34044

OS:
FreeBSD
Browser:
Firefox 3.0.4


View Profile WWW
« on: 29 March 2009, 09:32:55 »

задача: закрыть спам на сайтах.

есть черный список (black list) ip на сайте http://www.stopforumspam.com/ (есть и другие списки), список часто обновляется. В blacklist входя прокси-сервера, взломанные машины через которые боты пытаються спамить на все www сразу...

проще всего добаавить в ipfw таблицу, после блокировки максимум 1 спам сообщение за несколько суток или за неделю.

ipfw table:
Code:
add deny ip from table(1) to any

ee /root/spamstop.pl
Code:
#!/usr/bin/perl

# use File::Pid;
# my $pidfile = File::Pid->new( { file => '/var/run/x0.pid', } );
# my $pid = $pidfile->running;
# die "Service already running: $pid\n" if $pid;
# $pidfile->write;
## можно раскомментировать, это для того чтобы скрипт
## одновременно повторно не запустился

use LWP::Simple;

my $spam = get("http://www.stopforumspam.com/downloads/bannedips.csv");

# system("ipfw table 1 flush > /dev/null &") if (defined $spam);


open( IP, "ipfw table 1 list |" );
$/ = '';    # Включить режим чтения абзацев
my $use_ip = <IP>;
close IP;

# IP которые уже присутствуют в таблице не удаляются
# а добавляются новые тех которых нету
my %seen;
@seen{ return_ip($spam) } = ();
delete @seen{ return_ip($use_ip) };

#print keys %seen;

foreach (keys %seen) {
 print $_;
system("exec ipfw table 1 add ".$_ );
# system("exec ipfw table 1 add $_ > /dev/null &");

}

sub return_ip {
   # print $_[0];
   my $hash;
    $hash->{$1}++
      while $_[0] =~ /(\d+\.\d+\.\d+\.\d+)/smg xor
         grep { $_ > 255 } split /\./,
        $1;
    return keys %$hash;

}

# $pidfile->remove;
## можно раскомментировать, это для того чтобы скрипт
## одновременно повторно не запустился

exit;


crontab:
Code:
8 0  *   *   *  root  /root/spamstop.pl

или запускать скрипт, через каждых 3 часа:
Code:
0 */3 * * * root  /root/spamstop.pl


можно при старте системы добавить этот скрипт в /usr/local/etc/rc.d/

скрипт выполняется не быстро, 4-10 минут, грузит процессор, можно попробовать вариант быстрого добавления в ipfw таблицу ЧСВ python биндинг для ipfw бацаю


Code:
ipfw -a list | grep table
00150   1317     65171 deny ip from table(1) to any


========
========
========

вариант помягче:
http://forum.lissyara.su/viewtopic.php?f=14&t=16531#p159781

теперь в фаерволле у меня правило:

Code:
    00530 fwd 127.0.0.1,8013 tcp from table(1) to me dst-port 80

а 127.0.0.1:8013 слушает nginx
(основной вебсервер апач на 80 порту, а nginx только для быстрого отлупа "форум-спамера")

вот конфиг nginx

Code:
    #user  nobody;
    worker_processes  1;
    #error_log  logs/error.log;
    #error_log  logs/error.log  notice;
    #error_log  logs/error.log  info;
    #pid        logs/nginx.pid;
    events {
        worker_connections  10;
    }
    http {
        include       mime.types;
        default_type  application/octet-stream;
#log_format  main  '$remote_addr - $remote_user [$time_local] $request '
#                  '"$status" $body_bytes_sent "$http_referer" '
#                  '"$http_user_agent" "$http_x_forwarded_for"';
        #access_log  logs/access.log  main;
        sendfile        on;
        #tcp_nopush     on;
        #keepalive_timeout  0;
        keepalive_timeout  1;
        #gzip  on;
        server {
            listen       127.0.0.1:8013;
            server_name  localhost;
            #charset koi8-r;
            #access_log  logs/host.access.log  main;
            error_page  400 401 403 404 500 502 503 504 =200  /index.html;
            location / {
                root   /usr/local/www/nginx;
                index  index.html index.htm;
            }
        }
    }

а в index.html что-то типа этого

Code:
    <html>
    <head>
    <title>Welcome to zztop!</title>
    </head>
    <body bgcolor="white" text="black">
    <center><h1>You are seing this page, because you are in blacklist.
     </h1></center>
    <center><h2>Visit http://www.stopforumspam.com/ to check you IP,
          or contact me: email@was.here</h2></center>
    <center><h3>Best regards, St. Me.</h3></center>
    </body>
    </html>



Результат:
- nginx как "легкий" веб-сервер отлично и быстро отдает статику типа маленького html файлика, в котором написано что пользователь в стоп-листе
- если пользователь оказывается в стоп-листе, то он не тупо отфаерволивается, а редиректится на nginx, где его посылают, но красиво Smiley
- в апач запросы спамера не попадут вообще, т.е. он их не будет обрабатывать, и 1) нагружаться; 2) позволять роботам постить спам


######!!!!!!!!!!!!!!!!#########

UPD 2010.1.20


ссылка перестала работать http://www.stopforumspam.com/downloads/bannedips.csv

адсресс ссылки поменялся на http://www.stopforumspam.com/downloads/bannedips.zip, они список поставли в zip, не знаю зачем, но скрипт надо не много переделать:
Code:
#!/usr/bin/perl

# use File::Pid;
# my $pidfile = File::Pid->new( { file => '/var/run/x0.pid', } );
# my $pid = $pidfile->running;
# die "Service already running: $pid\n" if $pid;
# $pidfile->write;
## можно раскомментировать, это для того чтобы скрипт
## одновременно повторно не запустился

#my $spam = get("http://www.stopforumspam.com/downloads/bannedips.zip");

# system("ipfw table 1 flush > /dev/null &") if (defined $spam);

system("wget http://www.stopforumspam.com/downloads/bannedips.zip");

# use Archive::Zip;
# my $zip = Archive::Zip->new("bannedips.zip"); # Создаём объект
# $zip->extractTree(); # Разархивируем ZIP архив

system("/usr/local/bin/unzip bannedips.zip");

open( IPB, "bannedips.csv" );
$/ = '';    # Включить режим чтения абзацев
my $spam = <IPB>;
close IPB;

system("rm bannedips.csv");
system("rm bannedips.zip");

open( IP, "ipfw table 1 list |" );
$/ = '';    # Включить режим чтения абзацев
my $use_ip = <IP>;
close IP;

#####################
# IP которые уже присутствуют в таблице не удаляются
# а добавляются новые тех которых нету
my %seen;
@seen{ return_ip($spam) } = ();
delete @seen{ return_ip($use_ip) };


foreach ( keys %seen ) {
    print $_;
    system( "exec ipfw table 1 add " . $_ );
}

sub return_ip {

    my $hash;
    $hash->{$1}++
      while $_[0] =~ /(\d+\.\d+\.\d+\.\d+)/smg xor
          grep { $_ > 255 } split /\./,
        $1;
    return keys %$hash;

}

# $pidfile->remove;
## можно раскомментировать, это для того чтобы скрипт
## одновременно повторно не запустился

exit;


/etc/crontab:
(переменное окружение)
Code:
PATH=/etc:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin


блокировка спама (captcha, whitelist, blacklist, greylist для ящика)
« Last Edit: 28 January 2010, 19:40:12 by admin » Logged
admin
Администратор
Ветеран
*****
Offline Offline

Posts: 34044

OS:
FreeBSD
Browser:
Firefox 3.0.11


View Profile WWW
« Reply #1 on: 28 January 2010, 19:40:41 »

UPD 2010.1.20
Logged
Pages: [1]
  Print  
 
Jump to:  

1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
Powered by MySQL Powered by PHP Powered by SMF | SMF © 2006-2007, Simple Machines LLC | Sitemap Valid XHTML 1.0! Valid CSS!