mirror of
https://github.com/kuitoi/kuitoi-Server.git
synced 2026-10-26 06:00:29 +00:00
[+] rl.parse_console
This commit is contained in:
1 parent
c4a34c6630
commit
2eb7e8801b
2 files changed
+54
-7
No files matched your search
@@ -23,6 +23,8 @@ class TCPServer:
|
|||||||
self.port = port
|
self.port = port
|
||||||
self.run = False
|
self.run = False
|
||||||
self.rl = RateLimiter(50, 10, 300)
|
self.rl = RateLimiter(50, 10, 300)
|
||||||
|
console.add_command("rl", self.rl.parse_console, None, "RateLimiter menu",
|
||||||
|
{"rl": {"info": None, "unban": None, "ban": None, "help": None}})
|
||||||
|
|
||||||
async def auth_client(self, reader, writer):
|
async def auth_client(self, reader, writer):
|
||||||
client = self.Core.create_client(reader, writer)
|
client = self.Core.create_client(reader, writer)
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import asyncio
|
import asyncio
|
||||||
|
import textwrap
|
||||||
from collections import defaultdict, deque
|
from collections import defaultdict, deque
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
|
|
||||||
@@ -7,7 +8,7 @@ from core import utils
|
|||||||
|
|
||||||
class RateLimiter:
|
class RateLimiter:
|
||||||
def __init__(self, max_calls: int, period: float, ban_time: float):
|
def __init__(self, max_calls: int, period: float, ban_time: float):
|
||||||
self.log = utils.get_logger("DOSProtect")
|
self.log = utils.get_logger("RateLimiter")
|
||||||
self.max_calls = max_calls
|
self.max_calls = max_calls
|
||||||
self.period = timedelta(seconds=period)
|
self.period = timedelta(seconds=period)
|
||||||
self.ban_time = timedelta(seconds=ban_time)
|
self.ban_time = timedelta(seconds=ban_time)
|
||||||
@@ -15,6 +16,52 @@ class RateLimiter:
|
|||||||
self._banned_until = defaultdict(lambda: datetime.min)
|
self._banned_until = defaultdict(lambda: datetime.min)
|
||||||
self._notified = {}
|
self._notified = {}
|
||||||
|
|
||||||
|
def parse_console(self, x):
|
||||||
|
help_msg = textwrap.dedent("""\
|
||||||
|
|
||||||
|
RateLimiter menu:
|
||||||
|
info - list banned ip's
|
||||||
|
ban - put ip in banlist
|
||||||
|
unban - force remove ip from banlist
|
||||||
|
help - print that message""")
|
||||||
|
_banned_ips = [i for i in self._banned_until if self.is_banned(i, False)]
|
||||||
|
if len(x) > 0:
|
||||||
|
match x[0]:
|
||||||
|
case "info":
|
||||||
|
self.log.info(f"Trigger {self.max_calls}req/{self.period}. IP will be banned for {self.ban_time}.")
|
||||||
|
if len(_banned_ips) == 0:
|
||||||
|
return "No one ip in banlist."
|
||||||
|
else:
|
||||||
|
_msg = f"Banned ip{'' if len(_banned_ips) == 1 else 's'}: "
|
||||||
|
for ip in _banned_ips:
|
||||||
|
_msg += f"{ip}; "
|
||||||
|
return _msg
|
||||||
|
case "unban":
|
||||||
|
if len(x) == 2:
|
||||||
|
ip = x[1]
|
||||||
|
if ip in _banned_ips:
|
||||||
|
self._calls[ip].clear()
|
||||||
|
self._banned_until[ip] = datetime.now()
|
||||||
|
return f"{ip} removed from banlist."
|
||||||
|
return f"{ip} not banned."
|
||||||
|
else:
|
||||||
|
return 'rl unban <IP>'
|
||||||
|
case "ban":
|
||||||
|
if len(x) == 3:
|
||||||
|
ip = x[1]
|
||||||
|
sec = x[2]
|
||||||
|
if not sec.isdigit():
|
||||||
|
return f"{sec!r} is not digit."
|
||||||
|
self._calls[ip].clear()
|
||||||
|
self._banned_until[ip] = datetime.now() + timedelta(seconds=int(sec))
|
||||||
|
return f"{ip} banned until {self._banned_until[ip]}"
|
||||||
|
else:
|
||||||
|
return 'rl ban <IP> <sec>'
|
||||||
|
case _:
|
||||||
|
return help_msg
|
||||||
|
else:
|
||||||
|
return help_msg
|
||||||
|
|
||||||
async def notify(self, ip, writer):
|
async def notify(self, ip, writer):
|
||||||
if not self._notified[ip]:
|
if not self._notified[ip]:
|
||||||
self._notified[ip] = True
|
self._notified[ip] = True
|
||||||
@@ -26,14 +73,13 @@ class RateLimiter:
|
|||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def is_banned(self, ip: str) -> bool:
|
def is_banned(self, ip: str, _add_call=True) -> bool:
|
||||||
now = datetime.now()
|
now = datetime.now()
|
||||||
if now < self._banned_until[ip]:
|
if now < self._banned_until[ip]:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
now = datetime.now()
|
if _add_call:
|
||||||
self._calls[ip].append(now)
|
self._calls[ip].append(now)
|
||||||
|
|
||||||
while self._calls[ip] and self._calls[ip][0] + self.period < now:
|
while self._calls[ip] and self._calls[ip][0] + self.period < now:
|
||||||
self._calls[ip].popleft()
|
self._calls[ip].popleft()
|
||||||
|
|
||||||
@@ -49,8 +95,7 @@ class RateLimiter:
|
|||||||
async def handle_request(ip: str, rate_limiter: RateLimiter):
|
async def handle_request(ip: str, rate_limiter: RateLimiter):
|
||||||
if rate_limiter.is_banned(ip):
|
if rate_limiter.is_banned(ip):
|
||||||
print(f"Request from {ip} is banned at {datetime.now()}")
|
print(f"Request from {ip} is banned at {datetime.now()}")
|
||||||
print(f"{rate_limiter._banned_until[ip]}")
|
rate_limiter.parse_console(["info"])
|
||||||
return
|
|
||||||
|
|
||||||
|
|
||||||
async def server_simulation():
|
async def server_simulation():
|
||||||
|
|||||||
Reference in new issue
Block a user