# coding: utf-8 # +------------------------------------------------------------------- # | 宝塔Linux面板 x3 # +------------------------------------------------------------------- # | Copyright (c) 2015-2017 宝塔软件(http://bt.cn) All rights reserved. # +------------------------------------------------------------------- # | Author: lkq <1249648969@qq.com> # +------------------------------------------------------------------- # +-------------------------------------------------------------------- # | 告警消息队列 # +-------------------------------------------------------------------- import public,send_mail import time,os,sys,json class send_to_user: ''' 建立数据库 ''' def __init__(self): self.mail = send_mail.send_mail() if not public.M('sqlite_master').where('type=? AND name=?', ('table', 'send_settings')).count(): public.M('').execute('''CREATE TABLE "send_settings" ( "id" INTEGER PRIMARY KEY AUTOINCREMENT,"name" TEXT,"type" TEXT,"path" TEXT,"send_type" TEXT,"last_time" TEXT ,"time_frame" TEXT,"inser_time" TEXT DEFAULT'');''') if not public.M('sqlite_master').where('type=? AND name=?', ('table', 'send_msg')).count(): public.M('').execute('''CREATE TABLE "send_msg" ("id" INTEGER PRIMARY KEY AUTOINCREMENT,"name" TEXT,"send_type" TEXT,"msg" TEXT,"is_send" TEXT,"type" TEXT,"inser_time" TEXT DEFAULT '');''') '''设置表插入数据''' def insert_settings(self,name,type,path,send_type,time_frame=180): inser_time = self.dtchg(int(time.time())) last_time=int(time.time()) if public.M('send_settings').where('name=?',(name,)).count(): return False data={"name":name,"type":type,"path":path,"send_type":send_type,"time_frame":time_frame,"inser_time":inser_time,"last_time":last_time} return public.M('send_settings').insert(data) '''数据库插入''' def inser_send_msg(self,name,send_type,msg,type,inser_time): inser_time=self.dtchg(inser_time) if not inser_time:return False if public.M('send_msg').where('name=? and send_type=? and type=? and inser_time=?',(name,send_type,type,inser_time)).count():return False data={"name":name,"send_type":send_type,"msg":msg,"is_send":False,"type":type,"inser_time":inser_time} return public.M('send_msg').insert(data) def dtchg(self,x): try: time_local = time.localtime(float(x)) dt = time.strftime("%Y-%m-%d %H:%M:%S", time_local) return dt except: return False def get_ip(self): if os.path.exists('/www/server/panel/data/iplist.txt'): data=public.ReadFile('/www/server/panel/data/iplist.txt') return data.strip() else:return '127.0.0.1' def get_safe_logs(self, path,p=1,num=11): try: import cgi pythonV = sys.version_info[0] if not os.path.exists(path): return '111'; start_line = (p - 1) * num count = start_line + num fp = open(path, 'rb') buf = "" try: fp.seek(-1, 2) except: return [] if fp.read(1) == "\n": fp.seek(-1, 2) data = [] b = True n = 0 for i in range(count): while True: newline_pos = str.rfind(buf, "\n") pos = fp.tell() if newline_pos != -1: if n >= start_line: line = buf[newline_pos + 1:] try: tmp_data = json.loads(cgi.escape(line)) data.append(tmp_data) except: pass buf = buf[:newline_pos] n += 1 break else: if pos == 0: b = False break to_read = min(4096, pos) fp.seek(-to_read, 1) t_buf = fp.read(to_read) if pythonV == 3: t_buf = t_buf.decode('utf-8') buf = t_buf + buf fp.seek(-to_read, 1) if pos - to_read == 0: buf = "\n" + buf if not b: break; fp.close() except: data = [] return data ''' 读取数据库中的值、写入到数据库中 ''' def read_thread(self): if not public.M('send_settings').count():return False send_data=public.M('send_settings').field('id,name,type,path,send_type,inser_time,last_time,time_frame').select() print(send_data) for i in send_data: if (int(time.time())-int(i['last_time']))'+i2[1]+',触发告警时间:'+self.dtchg(int(time.time())),'json',i2[0]) public.writeFile(i['path'], '') public.M('send_settings').where("id=?", (i['id'],)).update({"last_time": int(time.time())}) continue if i['type']=='file': if os.path.exists(i['path']): self.inser_send_msg(i['name'], i['send_type'], '堡塔'+i['name']+'提醒您服务器'+self.get_ip()+'存在异常,详情请登陆面板查看'+i['name']+',触发告警时间:'+self.dtchg(int(time.time())), 'file', int(time.time())) public.M('send_settings').where("id=?", (i['id'],)).update({"last_time": int(time.time())}) os.system('rm -rf %s'%i['path']) if os.path.exists(i['path']):os.system('rm -rf %s'%i['path']) else: continue def send(self,title,body): tongdao = self.mail.get_settings() return self.mail.qq_smtp_send(tongdao['user_mail']['mail_list'], title=title, body=body) def send_dingding(self,count): return self.mail.dingding_send(count) def __write_log(self,name, msg): public.WriteLog(name+'告警', msg) '''发送消息线程''' def send_msg(self): if not public.M('send_msg').count(): return False send_msg=public.M('send_msg').where("is_send=?",(False,)).field('id,name,send_type,msg,is_send,type,inser_time').select() count=1 for i in send_msg: if count>=4:break settings=self.mail.get_settings() if i['send_type']=='mail': if not settings['user_mail']['user_name']:continue if i['name']=='Nginx防火墙' or i['name'] == 'Apache防火墙': if self.send(i['name'] + '提醒您' + self.get_ip() + '服务器正在遭受攻击', i['msg']): self.__write_log(i['name'], i['msg']) public.M('send_msg').where("id=?", (i['id'],)).update({"is_send": True}) else: if self.send(i['name']+'提醒您'+self.get_ip()+'服务器存在风险', i['msg']): self.__write_log(i['name'],i['msg']) public.M('send_msg').where("id=?", (i['id'],)).update({"is_send":True}) if i['send_type']=='dingding': if not settings['dingding']['dingding']: continue if i['name'] == 'Nginx防火墙' or i['name'] == 'Apache防火墙': if self.send(i['name'] + '提醒您' + self.get_ip() + '服务器正在遭受攻击', i['msg']): self.__write_log(i['name'], i['msg']) public.M('send_msg').where("id=?", (i['id'],)).update({"is_send": True}) else: if self.send_dingding(i['msg']): self.__write_log(i['name'], i['msg']) public.M('send_msg').where("id=?", (i['id'],)).update({"is_send": True}) count += 1 public.M('send_msg').where("is_send=?", (True,)).delete() def main(self): try: self.read_thread() self.send_msg() except: pass