Как защититься от DDOS-атак socketserver python

Я планирую включить сервер в разрабатываемое мной приложение (никакие передаваемые данные не будут конфиденциальными). Я настроил переадресацию портов на своем маршрутизаторе, которая указывает на сервер в сети. Вот фрагмент кода на стороне сервера:

import time
import threading
import socketserver
import ssl


class ThreadedTCPRequestHandler(socketserver.StreamRequestHandler):
    def handle(self):
        # Each new request is handled by this function.
        data = str(self.request.recv(4096), 'utf-8')
        print('Request received on {}'.format(time.ctime()))
        print('{} wrote: {}'.format(self.client_address[0], data))
        cur_thread = threading.current_thread()
        response = bytes("{}: {}".format(cur_thread.name, data), 'utf-8')
        self.request.sendall(response)


class TLSTCPServer(socketserver.TCPServer):
    def __init__(self, server_address, request_handler_class, certfile, keyfile, ssl_version=ssl.PROTOCOL_TLSv1_2,
                 bind_and_activate=True):
        socketserver.TCPServer.__init__(self, server_address, request_handler_class, bind_and_activate)
        self.certfile = certfile
        self.keyfile = keyfile
        self.ssl_version = ssl_version

    def get_request(self):
        newsocket, fromaddr = self.socket.accept()
        connstream = ssl.wrap_socket(newsocket,
                                     server_side=True,
                                     certfile=self.certfile,
                                     keyfile=self.keyfile,
                                     ssl_version=self.ssl_version)
        return connstream, fromaddr


class ThreadedTCPServer(socketserver.ThreadingMixIn, TLSTCPServer):
    pass


if __name__ == "__main__":
    HOST, PORT = "0.0.0.0", 6001

    # Creates a server that handles each request on a separate thread. "cert.pem" is the TLS certificate and "key.pem"
    # is the TLS private key (kept only on the server).
    server = ThreadedTCPServer((HOST, PORT), ThreadedTCPRequestHandler, "cert.pem", "key.pem")
    ip, port = server.server_address

    print('Started server\n')
    server.serve_forever()

А вот и клиентский код:

import socket
import time
import ssl

HOST = 'localhost'  # This should be the server's public IP when used in production code
PORT = 6001

data = 'Hello!'
start_time = time.time()

try:
    # Connect to server and send data
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    ssl_sock = ssl.wrap_socket(sock,
                               ca_certs = "cert.pem",
                               cert_reqs=ssl.CERT_REQUIRED,
                               ssl_version=ssl.PROTOCOL_TLSv1_2)

    ssl_sock.connect((HOST, PORT))
    ssl_sock.sendall(data.encode())

    # Receive data from the server and shut down
    received = ssl_sock.recv(4096)

    elapsed_tie = round(time.time() - start_time, 2)
    print("Sent:     {}".format(data))
    print("Received: {}".format(received.decode('utf-8')))
    print("Elapsed:  {}s \n".format(elapsed_tie))
    ssl_sock.close()

except Exception as e:
    print(format(e))

Обратите внимание, что cert.pem и key.pem генерируются с помощью этой команды в терминале Mac или Linux: openssl req -newkey rsa:4096 -nodes -sha512 -x509 -days 3650 -nodes -out cert.pem -keyout key.pem

Сервер использует TLS для защиты данных, а запросы обрабатываются в отдельных потоках. Объем вычислений, выполняемых для каждого запроса, будет относительно небольшим, поскольку он будет в основном состоять из чтения и записи небольших объемов данных в базу данных с каждым запросом.

Меня больше всего беспокоит то, что кто-то злонамеренно может определить публичный IP-адрес сервера и выполнить DDOS-атаку. Один из способов смягчить это - отклонить слишком частые запросы с одного и того же клиентского адреса. Есть ли другие способы смягчить такие атаки? Кроме того, стоит ли запускать безопасный сервер на Python или мне стоит поискать в другом месте? Заранее спасибо.

--- РЕДАКТИРОВАТЬ ---

Я думал проверить, не делает ли один и тот же пользователь слишком много запросов за определенное время. Поскольку запросы выполняются по таймеру (скажем, 5 секунд), любые запросы, выполняемые чаще, считаются подозрительными. Пока входящие запросы не перегружают полосу пропускания маршрутизатора, теоретически я должен иметь возможность отклонять некоторые запросы. Однако, если несколько машин делают запросы из одной и той же сети, я не могу просто смотреть на общедоступные IP-адреса входящих запросов, так как я могу отклонять совершенно действительные запросы. Есть ли какой-либо идентификатор, позволяющий идентифицировать машину, отправляющую запрос?

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
0
2 945
1

Ответы 1

Когда до вас доходит DDoS-атака, уже слишком поздно. Пакеты прибыли на ваш сервер и заполняют ваш канал. Что бы вы ни делали, они уже есть - многие из них. Вы можете отказаться от них, но другие люди все равно не смогут связаться с вами.

Защита от DDoS-атак должна осуществляться по восходящей линии связи кем-то, кто сможет решить, является ли пакет вредоносным или нет. Это волшебная операция, за которую такие компании, как Cloudflare или Akamai, заставляют вас много платить.

Другая возможность - изменить вашу запись DNS так, чтобы точка находилась где-то еще во время атаки. Это действительно здорово, чтобы ваши клиенты знали, что ваш сайт «находится на обслуживании, скоро вернется».

Я думал проверить, не делает ли один и тот же пользователь слишком много запросов за определенное время. Поскольку запросы выполняются по таймеру (скажем, 5 секунд), любые запросы, выполняемые чаще, считаются подозрительными. Пока входящие запросы не перегружают полосу пропускания маршрутизатора, теоретически я должен иметь возможность отклонять некоторые запросы. Однако, если несколько машин делают запросы из одной и той же сети, я не могу просто смотреть на общедоступные IP-адреса входящих запросов, так как я могу отклонять совершенно действительные запросы. Есть ли какой-либо идентификатор, позволяющий идентифицировать машину, отправляющую запрос?

aL_eX 12.03.2018 04:04

Первое, о чем вы упомянули, называется дросселирование. Это защищает (в вашем случае) учетную запись пользователя от перебора. Вторая часть (как однозначно идентифицировать устройства) - это на самом деле упомянутая мною «волшебная операция»: способность решать, является ли конкретный вызов / соединение законным или нет. Для этого нет простых решений, и сервисы по предотвращению DDoS-атак продают именно эти знания. На самом деле вы можете защитить учетную запись от грубой силы (путем регулирования IP-адресов и, возможно, блокировки учетной записи - это вопрос анализа рисков), но не более того.

WoJ 12.03.2018 21:39

Другие вопросы по теме