ban user with cloudflare

This commit is contained in:
Benny
2022-09-09 18:07:55 +08:00
parent 3589e9bae3
commit 19807e20fd
5 changed files with 55 additions and 29 deletions

View File

@@ -328,15 +328,15 @@ def approve_spam(call):
bot.delete_message(call.message.chat.id, call.message.message_id)
@bot.callback_query_handler(func=lambda call: re.findall(r"deny", call.data))
def deny_spam(call):
obj_id = re.findall(r"deny(\S*)", call.data)[0]
@bot.callback_query_handler(func=lambda call: re.findall(r"ban", call.data))
def ban_spam(call):
obj_id = re.findall(r"ban(\S*)", call.data)[0]
data = {
"obj_id": obj_id,
"token": TOKEN
}
requests.delete(f"{DOMAIN}api/admin/spam", json=data)
bot.answer_callback_query(call.id, 'Denied')
bot.answer_callback_query(call.id, 'Banned')
bot.delete_message(call.message.chat.id, call.message.message_id)

View File

@@ -37,7 +37,7 @@ from database import (AnnouncementResource, BlacklistResource, CaptchaResource,
NameResource, NotificationResource, OtherResource, Redis,
ResourceLatestResource, ResourceResource, TopResource,
UserEmailResource, UserResource)
from utils import check_spam, send_mail, ts_date
from utils import check_spam, send_mail, ts_date, Cloudflare
lib_path = pathlib.Path(__file__).parent.parent.joinpath("yyetsbot").resolve().as_posix()
sys.path.append(lib_path)
@@ -46,6 +46,7 @@ from fansub import BD2020, XL720, NewzmzOnline, ZhuixinfanOnline, ZimuxiaOnline
mongo_host = os.getenv("mongo") or "localhost"
DOUBAN_SEARCH = "https://www.douban.com/search?cat=1002&q={}"
DOUBAN_DETAIL = "https://movie.douban.com/subject/{}/"
cf = Cloudflare()
class Mongo:
@@ -93,6 +94,7 @@ class OtherMongoResource(OtherResource, Mongo):
self.db["yyets"].update_many({}, {"$set": {"data.info.views": 0}})
def import_ban_user(self):
# TODO ban IP as well?
usernames = self.db["users"].find({"status.disable": True}, projection={"username": True})
r = Redis().r
r.delete("user_blacklist")
@@ -1091,10 +1093,15 @@ class ResourceLatestMongoResource(ResourceLatestResource, Mongo):
class SpamProcessMongoResource(Mongo):
def delete_spam(self, obj_id: "str"):
def ban_spam(self, obj_id: "str"):
obj_id = ObjectId(obj_id)
logging.info("Deleting spam %s", obj_id)
self.db["spam"].delete_one({"_id": obj_id})
spam = self.db["spam"].find_one({"_id": obj_id})
username = spam["username"]
self.db["spam"].delete_many({"username": username})
# TODO disable it for now
# self.db["comment"].delete_many({"username": username})
cf.ban_new_ip(spam["ip"])
return {"status": True}
def restore_spam(self, obj_id: "str"):
@@ -1121,8 +1128,8 @@ class SpamProcessMongoResource(Mongo):
"callback_data": f"approve{obj_id}"
},
{
"text": "deny",
"callback_data": f"deny{obj_id}"
"text": "ban",
"callback_data": f"ban{obj_id}"
}
]
]

View File

@@ -28,11 +28,11 @@ from tornado import escape, gen, web
from tornado.concurrent import run_on_executor
from database import CaptchaResource, Redis
from utils import add_cf_blacklist
from utils import Cloudflare
escape.json_encode = lambda value: json.dumps(value, ensure_ascii=False)
logging.basicConfig(level=logging.INFO)
cf = Cloudflare()
if getattr(sys, '_MEIPASS', None):
adapter = "SQLite"
else:
@@ -82,7 +82,7 @@ class SecurityHandler(web.RequestHandler):
else:
ex = (count - 10) * 600
if count >= 30:
add_cf_blacklist(ip)
cf.ban_new_ip(ip)
self.r.set(ip, count, ex)
user = self.get_current_user()
if user:
@@ -991,7 +991,7 @@ class SpamProcessHandler(BaseHandler):
return getattr(self.instance, method)(obj_id)
else:
self.set_status(HTTPStatus.FORBIDDEN)
return {"status": False, "message": "this token is not allowed to access this API"}
return {"status": False, "message": "This token is not allowed to access this API"}
@gen.coroutine
def post(self):
@@ -999,4 +999,4 @@ class SpamProcessHandler(BaseHandler):
@gen.coroutine
def delete(self):
self.write(self.process("delete_spam"))
self.write(self.process("ban_spam"))

View File

@@ -32,9 +32,10 @@ from handler import (AnnouncementHandler, BlacklistHandler, CaptchaHandler,
UserEmailHandler, UserHandler)
from migration.douban_sync import sync_douban
from Mongo import OtherMongoResource, ResourceLatestMongoResource
from utils import Cloudflare
enable_pretty_logging()
cf = Cloudflare()
if os.getenv("debug"):
logging.basicConfig(level=logging.DEBUG)
@@ -106,6 +107,7 @@ if __name__ == "__main__":
scheduler.add_job(entry_dump, trigger=CronTrigger.from_crontab("2 2 1 * *"))
scheduler.add_job(ResourceLatestMongoResource().refresh_latest_resource, 'interval', hours=1)
scheduler.add_job(OtherMongoResource().import_ban_user, 'interval', seconds=300)
scheduler.add_job(cf.clear_fw, trigger=CronTrigger.from_crontab("0 0 */5 * *"))
scheduler.start()
options.define("p", default=8888, help="running port", type=int)

View File

@@ -66,23 +66,40 @@ def check_spam(ip, ua, author, content) -> int:
return 0
def add_cf_blacklist(ip):
logging.warning("Cloudflare: Blacklisting %s", ip)
zone_id = "b8e2d2fa75c6f7dc3c2e478e27f3061b"
filter_id = "cc6c810f7f2941d28a672bfb6ac6bebe"
api = f"https://api.cloudflare.com/client/v4/zones/{zone_id}/filters/{filter_id}"
s = requests.Session()
s.headers.update({"Authorization": "Bearer %s" % os.getenv("CF_TOKEN")})
expr = s.get(api).json()["result"]["expression"]
if ip not in expr:
class Cloudflare:
def __init__(self):
self.zone_id = "b8e2d2fa75c6f7dc3c2e478e27f3061b"
self.filter_id = "9e1e9139bcbe400c8b2620ac117a77d8"
self.endpoint = f"https://api.cloudflare.com/client/v4/zones/{self.zone_id}/filters/{self.filter_id}"
self.session = requests.Session()
self.session.headers.update({"Authorization": "Bearer %s" % os.getenv("CF_TOKEN")})
def get_old_expr(self):
return self.session.get(self.endpoint).json()["result"]["expression"]
def ban_new_ip(self, ip):
logging.info("Blacklisting IP %s", ip)
expr = self.get_old_expr()
if ip not in expr:
body = {
"id": self.filter_id,
"paused": False,
"expression": f"{expr} or (ip.src eq {ip})"
}
resp = self.session.put(self.endpoint, json=body)
logging.info(resp.json())
def clear_fw(self):
logging.info("Clearing firewall rules")
body = {
"id": filter_id,
"id": self.filter_id,
"paused": False,
"expression": f"{expr} or (ip.src eq {ip})"
"expression": "(ip.src eq 192.168.2.1)"
}
resp = s.put(api, json=body)
print(resp.json())
self.session.put(self.endpoint, json=body)
if __name__ == '__main__':
add_cf_blacklist("192.168.2.1")
cf = Cloudflare()
cf.clear_fw()
cf.ban_new_ip("3.3.3.3")