Nginx-ru mailing list archive (nginx-ru@sysoev.ru)
 
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Месть ботам
 
 
adept wrote:
 
Проще сделать иптаблесом, в нем есть
замечательная штука, TARPIT
 
 
 Словно самому сложно написать. За два кило в коде можно ещё с рюшками и 
финтифлюшками.
 Аттачу что писал полгода назад во время очередного ддоса. В локальном 
каталоге ищет файл tarpit.html с полным текстом ответа (с заголовками). 
Режет окно, слушает запрос и начинает отдавать содержимое файла по байту 
в секунду. Рекомендую не делать файл совсем большим так как за сутки 
соответственно отдаст только 85k.
 Минус - жрёт память, в районе гига на 100k подключений. Сейчас бы писал 
на lua, да лень уже.
--
Sphinx of black quartz judge my vow.
 #!/usr/bin/env python-shared
# vim:set fileencoding=utf-8
from __future__ import division, print_function, unicode_literals
import gevent.monkey
gevent.monkey.patch_all()
import datetime, gevent.pool, signal, socket, sys
answer = []
pool = gevent.pool.Pool()
port = 8081
pitted = {}
sockets = set()
for line in open('tarpit.html', 'rb'):
        answer += line
def serve_one(conn, addr):
        global answer, sockets
        sockets.add(conn)
        buf = ''
        if addr[0] in pitted:
                pitted[addr[0]] += 1
        else:
                pitted[addr[0]] = 1
        try:
                conn.settimeout(300)
                while True:
                        gevent.sleep(1)
                        byte = conn.recv(1)
                        if byte == '':
                                break
                        if byte in ('\r', '\n'):
                                buf += byte
                                if buf == '\r\n\r\n':
                                        break
                        else:
                                buf = ''
                x = 0
                while True:
                        gevent.sleep(1)
                        conn.settimeout(300)
                        x += conn.send(answer[x])
                        conn.settimeout(0)
                        try:
                                conn.recv(1)
                        except socket.error as err:
                                if err[0] == 35:
                                        pass
                                else:
                                        raise err
                        if x >= len(answer):
                                break
                conn.shutdown(socket.SHUT_RDWR)
                conn.close()
        except socket.error as err:
                if not type(err) == socket.timeout:
                        if not err[0] in [32, 54]:
                                print('disconnected:', repr(err), 'at line', 
sys.exc_info()[2].tb_lineno)
                        if not err[0] in [1, 32, 54]:
                                raise err
        finally:
                conn.close()
        if pitted[addr[0]] == 1:
                del pitted[addr[0]]
        else:
                pitted[addr[0]] -= 1
        sockets.discard(conn)
def listen(pool):
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, 1)
        s.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 1)
        sockets.add(s)
        s.bind(('', port))
        s.listen(256)
        print('Bound to port:', port)
        while True:
                try:
                        pool.spawn(serve_one, *s.accept())
                except socket.error as err:
                        if err[0] == 53:
                                pass
                        else:
                                raise(err)
def siginfo_handler(signum, frame):
        print('tarpitted(', port, '):', len(pitted), 'addresses,', len(pool) - 
1, 'connections')
signal.signal(signal.SIGINFO, siginfo_handler)
try:
        pool.spawn(listen, pool)
        pool.join()
except KeyboardInterrupt:
        pass
finally:
        print('killing sockets')
        for socket in sockets:
                socket.close()
        sys.exit(1)
_______________________________________________
nginx-ru mailing list
nginx-ru@xxxxxxxxx
http://mailman.nginx.org/mailman/listinfo/nginx-ru 
 
 |