title: How to protect against DDOS attack socketserver python
body: <p>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:</p>
  
  <pre><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()
  </code></pre>
  
  <p>And here is the client code:</p>
  
  <pre><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))
  </code></pre>
  
  <p>Note that <code>cert.pem</code> and <code>key.pem</code> are generated with this command in a Mac or Linux terminal: <code>openssl req -newkey rsa:4096 -nodes -sha512 -x509 -days 3650 -nodes -out cert.pem -keyout key.pem</code></p>
  
  <p>The server uses TLS to secure the data, and requests are handled on separate threads. 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.</p>
  
  <p>My main concern is that somebody acting maliciously could figure out what the server's public IP address is and perform a DDOS attack. 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? Thank you in advance.</p>
  
  <p>--- EDIT ---</p>
  
  <p>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. 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. Is there any ID identifiable to the machine making the request?</p>