简体   繁体   English

如何防止DDOS攻击socketserver python

[英]How to protect against DDOS attack socketserver python

I'm planning on incorporating a server into an application I'm developing (none of the data being transferred will be sensitive). 我正计划将服务器合并到正在开发的应用程序中(传输的数据都不会敏感)。 I've set up port forwarding on my router that points to the server on the network. 我已经在路由器上设置了指向网络上服务器的端口转发。 Here is a snippet of the server side code: 这是服务器端代码的片段:

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()

And here is the client code: 这是客户端代码:

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))

Note that cert.pem and key.pem are generated with this command in a Mac or Linux terminal: openssl req -newkey rsa:4096 -nodes -sha512 -x509 -days 3650 -nodes -out cert.pem -keyout key.pem 请注意, cert.pemkey.pem是在Mac或Linux终端中使用此命令生成的: openssl req -newkey rsa:4096 -nodes -sha512 -x509 -days 3650 -nodes -out cert.pem -keyout key.pem

The server uses TLS to secure the data, and requests are handled on separate threads. 服务器使用TLS保护数据安全,并且请求在单独的线程上处理。 The amount of computation done for each request will be relatively small, as it would mainly consist of reading and writing small amounts of data to a database with each request. 每个请求完成的计算量将相对较小,因为它主要包括随每个请求向数据库读取和写入少量数据。

My main concern is that somebody acting maliciously could figure out what the server's public IP address is and perform a DDOS attack. 我主要担心的是,有人恶意行为可能会弄清楚服务器的公共IP地址是什么,并进行DDOS攻击。 One way I can think to mitigate this is to deny requests made too frequently from the same client address. 我想减轻这种情况的一种方法是拒绝来自同一客户地址的请求过于频繁。 Are there any other ways to mitigate such attacks? 还有其他方法可以减轻此类攻击吗? Also, is running a secure server in Python a good idea or should I be looking elsewhere? 另外,在Python中运行安全服务器是个好主意还是应该在其他地方寻找? Thank you in advance. 先感谢您。

--- EDIT --- -编辑-

I was thinking of checking whether the same user makes too many requests in a certain amount of time. 我正在考虑检查同一用户在一定时间内是否发出过多请求。 Since the requests are on a timer (say, 5 seconds) any requests made more frequently are deemed suspicious. 由于请求是按计时器(例如5秒)进行的,因此任何较频繁发出的请求都被视为可疑。 As long as the incoming requests don't saturate the router's bandwidth, I should, in theory, be able to deny some requests. 只要传入的请求不会使路由器的带宽饱和,从理论上讲,我应该能够拒绝某些请求。 However, if multiple machines make requests from the same network, I can't just look at the incoming requests' public IP addresses, since I could be denying perfectly valid requests. 但是,如果有多台计算机从同一个网络发出请求,则我不能仅查看传入请求的公共IP地址,因为我可能会拒绝完全有效的请求。 Is there any ID identifiable to the machine making the request? 发出请求的机器是否可以识别任何ID?

When a DDoS attack gets to you it is too late. 当DDoS攻击到达您时,为时已晚。 The packets arrived to your server and are filling up your pipe. 数据包到达您的服务器,并正在填充您的管道。 No matter what you do, they are already there - many of them. 无论您做什么,它们都已经存在-很多。 You can discard them but others won't be able to reach you anyway. 您可以丢弃它们,但其他人无论如何都无法找到您。

DDoS protection must be done uplink, by someone who will have the capacity to decide whether a packet is malicious or not. DDoS保护必须由能够确定数据包是否为恶意数据的人员在上行链路上进行。 This is a magical operation which companies such as Cloudflare or Akamai make you pay a lot for. 这是一项神奇的操作,Cloudflare或Akamai等公司会让您为此付出高昂的代价。

Another possibility is to change your DNS entry to point is somewhere else during the attack. 另一种可能性是在攻击过程中将DNS条目更改为指向其他位置。 This is really a nice to have, so that your customers know that your site is "under maintenance, back soon". 真是太好了,让您的客户知道您的网站“正在维护中,很快就会回来”。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM