Added MAX_CONNECTION_RATE, MAX_COMMAND_RATE for throttling various aspects of input as a DoS measure as per #640.
This commit is contained in:
parent
f5eeba72e0
commit
37763ceca5
2 changed files with 31 additions and 11 deletions
|
|
@ -1,17 +1,19 @@
|
||||||
"""
|
"""
|
||||||
Sessionhandler for portal sessions
|
Sessionhandler for portal sessions
|
||||||
"""
|
"""
|
||||||
from collections import deque
|
|
||||||
from time import time
|
from time import time
|
||||||
from twisted.internet import reactor, task
|
from twisted.internet import reactor
|
||||||
|
from django.conf import settings
|
||||||
from evennia.server.sessionhandler import SessionHandler, PCONN, PDISCONN, PCONNSYNC
|
from evennia.server.sessionhandler import SessionHandler, PCONN, PDISCONN, PCONNSYNC
|
||||||
|
|
||||||
_CONNECTION_RATE = 5.0
|
# module import
|
||||||
_MIN_TIME_BETWEEN_CONNECTS = 1.0 / _CONNECTION_RATE
|
|
||||||
_MOD_IMPORT = None
|
_MOD_IMPORT = None
|
||||||
|
|
||||||
#_MAX_CMD_RATE = 80.0
|
# throttles
|
||||||
#_ERROR_COMMAND_OVERFLOW = "You entered commands too fast. Wait a moment and try again."
|
_MIN_TIME_BETWEEN_CONNECTS = 1.0 / float(settings.MAX_CONNECTION_RATE) if float(settings.MAX_CONNECTION_RATE) > 0 else 1.0 / 5.0
|
||||||
|
_MIN_TIME_BETWEEN_CMDS = 1.0 / float(settings.MAX_COMMAND_RATE) if float(settings.MAX_COMMAND_RATE) > 0 else -10
|
||||||
|
_ERROR_COMMAND_OVERFLOW = settings.COMMAND_RATE_WARNING
|
||||||
|
|
||||||
#------------------------------------------------------------
|
#------------------------------------------------------------
|
||||||
# Portal-SessionHandler class
|
# Portal-SessionHandler class
|
||||||
|
|
@ -66,9 +68,8 @@ class PortalSessionHandler(SessionHandler):
|
||||||
session.sessid = self.latest_sessid
|
session.sessid = self.latest_sessid
|
||||||
|
|
||||||
now = time()
|
now = time()
|
||||||
current_rate = 1.0 / (now - self.time_last_connect)
|
|
||||||
|
|
||||||
if current_rate > _CONNECTION_RATE:
|
if now - self.time_last_connect < _MIN_TIME_BETWEEN_CONNECTS:
|
||||||
# we have too many connections per second. Delay.
|
# we have too many connections per second. Delay.
|
||||||
#print " delaying connecting", session.sessid
|
#print " delaying connecting", session.sessid
|
||||||
reactor.callLater(_MIN_TIME_BETWEEN_CONNECTS, self.connect, session)
|
reactor.callLater(_MIN_TIME_BETWEEN_CONNECTS, self.connect, session)
|
||||||
|
|
@ -80,9 +81,9 @@ class PortalSessionHandler(SessionHandler):
|
||||||
reactor.callLater(0.5, self.connect, session)
|
reactor.callLater(0.5, self.connect, session)
|
||||||
return
|
return
|
||||||
|
|
||||||
# sync with server-side
|
|
||||||
|
|
||||||
self.time_last_connect = now
|
self.time_last_connect = now
|
||||||
|
|
||||||
|
# sync with server-side
|
||||||
sessdata = session.get_sync_data()
|
sessdata = session.get_sync_data()
|
||||||
self.sessions[session.sessid] = session
|
self.sessions[session.sessid] = session
|
||||||
session.server_connected = True
|
session.server_connected = True
|
||||||
|
|
@ -290,7 +291,13 @@ class PortalSessionHandler(SessionHandler):
|
||||||
serialized before passed on.
|
serialized before passed on.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
# data throttle (anti DoS measure)
|
||||||
|
prev_cmd_last = session.cmd_last
|
||||||
session.cmd_last = time()
|
session.cmd_last = time()
|
||||||
|
if session.cmd_last - prev_cmd_last < _MIN_TIME_BETWEEN_CMDS:
|
||||||
|
self.data_out(session.sessid, text=_ERROR_COMMAND_OVERFLOW)
|
||||||
|
return
|
||||||
|
# relay data to Server
|
||||||
self.portal.amp_protocol.call_remote_MsgPortal2Server(session.sessid,
|
self.portal.amp_protocol.call_remote_MsgPortal2Server(session.sessid,
|
||||||
msg=text,
|
msg=text,
|
||||||
data=kwargs)
|
data=kwargs)
|
||||||
|
|
|
||||||
|
|
@ -71,7 +71,7 @@ WEBSOCKET_CLIENT_ENABLED = True
|
||||||
WEBSOCKET_CLIENT_PORT = 8001
|
WEBSOCKET_CLIENT_PORT = 8001
|
||||||
# Interface addresses to listen to. If 0.0.0.0, listen to all. Use :: for IPv6.
|
# Interface addresses to listen to. If 0.0.0.0, listen to all. Use :: for IPv6.
|
||||||
WEBSOCKET_CLIENT_INTERFACE = '0.0.0.0'
|
WEBSOCKET_CLIENT_INTERFACE = '0.0.0.0'
|
||||||
# Actual URL for webclient component to reach the websocket.
|
# Actual URL for webclient component to reach the websocket.
|
||||||
# The WEBSOCKET_CLIENT_PORT will be automatically appended to this URL.
|
# The WEBSOCKET_CLIENT_PORT will be automatically appended to this URL.
|
||||||
WEBSOCKET_CLIENT_URL = "ws://localhost"
|
WEBSOCKET_CLIENT_URL = "ws://localhost"
|
||||||
# Activate SSH protocol communication (SecureShell)
|
# Activate SSH protocol communication (SecureShell)
|
||||||
|
|
@ -179,6 +179,19 @@ AMP_INTERFACE = '127.0.0.1'
|
||||||
# be necessary (use @server to see how many objects are in the idmapper
|
# be necessary (use @server to see how many objects are in the idmapper
|
||||||
# cache at any time). Setting this to None disables the cache cap.
|
# cache at any time). Setting this to None disables the cache cap.
|
||||||
IDMAPPER_CACHE_MAXSIZE = 200 # (MB)
|
IDMAPPER_CACHE_MAXSIZE = 200 # (MB)
|
||||||
|
# This determines how many connections per second the Portal should
|
||||||
|
# accept, as a DoS countermeasure. If the rate exceeds this number, incoming
|
||||||
|
# connections will be queued to this rate, so none will be lost.
|
||||||
|
# Must be set to a value > 0.
|
||||||
|
MAX_CONNECTION_RATE = 5
|
||||||
|
# Determine how many commands per second a given Session is allowed
|
||||||
|
# to send to the Portal via a connected protocol. Too high rate will
|
||||||
|
# drop the command and echo a warning. Note that this will also cap
|
||||||
|
# OOB messages so don't set it too low if you expect a lot of events
|
||||||
|
# from the client! To turn the limiter off, set to <= 0.
|
||||||
|
MAX_COMMAND_RATE = 80
|
||||||
|
# The warning to echo back to users if they send commands too fast
|
||||||
|
COMMAND_RATE_WARNING ="You entered commands too fast. Wait a moment and try again."
|
||||||
|
|
||||||
######################################################################
|
######################################################################
|
||||||
# Evennia Database config
|
# Evennia Database config
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue