我计划将服务器集成到我正在开发的应用程序中(传输的数据都不会是敏感的)。我在我的路由器上设置了端口转发,它指向网络上的服务器。以下是服务器端代码的一个片段:
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地址,因为我可能会拒绝完全有效的请求。发出请求的机器是否有可识别的ID?
发布于 2018-03-10 23:57:25
当DDoS攻击攻击到您时,为时已晚。数据包已到达您的服务器,并且正在填满您的管道。无论你做什么,它们都已经存在了--很多都是。你可以丢弃它们,但其他人无论如何都无法联系到你。
DDoS保护必须在上行链路上进行,由能够确定数据包是否是恶意数据包的人来完成。这是一个神奇的操作,Cloudflare或Akamai等公司让你为此付出了很多代价。
另一种可能是在攻击期间将DNS条目更改为指向其他位置。这真的很好,让你的客户知道你的网站“正在维护中,很快就会回来”。
https://stackoverflow.com/questions/49204360
复制相似问题