首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何防御DDOS攻击socketserver python

如何防御DDOS攻击socketserver python
EN

Stack Overflow用户
提问于 2018-03-10 09:13:13
回答 1查看 4K关注 0票数 0

我计划将服务器集成到我正在开发的应用程序中(传输的数据都不会是敏感的)。我在我的路由器上设置了端口转发,它指向网络上的服务器。以下是服务器端代码的一个片段:

代码语言:javascript
运行
复制
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()

下面是客户端代码:

代码语言:javascript
运行
复制
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.pemkey.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地址,因为我可能会拒绝完全有效的请求。发出请求的机器是否有可识别的ID?

EN

回答 1

Stack Overflow用户

发布于 2018-03-10 23:57:25

当DDoS攻击攻击到您时,为时已晚。数据包已到达您的服务器,并且正在填满您的管道。无论你做什么,它们都已经存在了--很多都是。你可以丢弃它们,但其他人无论如何都无法联系到你。

DDoS保护必须在上行链路上进行,由能够确定数据包是否是恶意数据包的人来完成。这是一个神奇的操作,Cloudflare或Akamai等公司让你为此付出了很多代价。

另一种可能是在攻击期间将DNS条目更改为指向其他位置。这真的很好,让你的客户知道你的网站“正在维护中,很快就会回来”。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49204360

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档