class SecurityHandler(web.RequestHandler): key = "user_blacklist" def __init__(self, application, request, **kwargs): super().__init__(application, request, **kwargs) self.r = Redis().r def prepare(self): if self.check_request(): self.set_status(HTTPStatus.FORBIDDEN) self.finish() def data_received(self, chunk): pass def check_request(self): ban = self.__ip_check() user = self.__user_check() result = ban or user if result: self.ban() return result def get_real_ip(self): x_real = self.request.headers.get("X-Real-IP") remote_ip = self.request.remote_ip logging.debug("X-Real-IP:%s, Remote-IP:%s", x_real, remote_ip) return x_real or remote_ip def ban(self): ip = self.get_real_ip() self.r.incr(ip) count = int(self.r.get(ip)) # ban rule: (count-10)*600 if count <= 10: ex = 120 else: ex = (count - 10) * 600 if count >= 30: add_cf_blacklist(ip) self.r.set(ip, count, ex) user = self.get_current_user() if user: self.r.hincrby(self.key, user) def get_current_user(self) -> str: username = self.get_secure_cookie("username") or b"" return username.decode("u8") def __user_check(self): count = self.r.hget(self.key, self.get_current_user()) or 0 count = int(count) if count >= 20: return True def __ip_check(self): d = self.r.get(self.get_real_ip()) or 0 if int(d) >= 10: return True