找到(/www/server/panel/plugin/free_waf/free_waf_main.py)这个文件
给这个类增加一个IP归属地显示的方法。代码如下(大约17行下面):- def getIpLocation(self, ip): url = f"https://www.wenyunfang.com/e/extend/chat/info.php?enews=ipcha&ip={ip}" try: response = requests.get(url) if response.status_code == 200: data = response.json() if data["code"] == 1: location = data["ip2"] return location else: return "查询失败,错误代码: " + str(data["code"]) else: return f"请求失败,状态码: {response.status_code}"
复制代码 那我们在日志获取方法的类新增IP归属地显示。仍然是这个文件。(get_safe_logs)为方法,直接贴方法了哈- def get_safe_logs(self, get): try: import cgi pythonV = sys.version_info[0] if 'drop_ip' in get: path = '/www/server/free_waf/drop_ip.log' num = 14 else: path = '/www/wwwlogs/free_waf_log/' + get.siteName + '_' + get.toDate + '.log' num = 10 if not os.path.exists(path): return [] p = 1 if 'p' in get: p = int(get.p) 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 c = 0 while c < 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:] if line: try: tmp_data = json.loads(cgi.escape(line)) for i in range(len(tmp_data)): if i == 7: tmp_data[i] = str(tmp_data[i]).replace('&', '&').replace('<', '<').replace( '>', '>') else: tmp_data[i] = cgi.escape(str(tmp_data[i]), True) ip = tmp_data[1] ip_location = self.getIpLocation(ip) tmp_data.append(ip_location) data.append(tmp_data) except: c -= 1 n -= 1 pass else: c -= 1 n -= 1 buf = buf[:newline_pos] n += 1 c += 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', errors="ignore") buf = t_buf + buf fp.seek(-to_read, 1) if pos - to_read == 0: buf = "\n" + buf if not b: break fp.close() if 'drop_ip' in get: drop_iplist = self.get_waf_drop_ip(None) stime = time.time() setss = [] for i in range(len(data)): if (float(stime) - float(data[i][0])) < float(data[i][4]) and not data[i][1] in setss: setss.append(data[i][1]) data[i].append(data[i][1] in drop_iplist) else: data[i].append(False) except: return public.get_error_info() data = [] return data
复制代码 至于怎么渲染出来,自行修改/www/server/panel/plugin/free_waf/index.html 里面那段render_site_logs,比如小编的- // 渲染站点日志 render_site_logs: function (obj, callback) { var _this = this; this.get_safe_logs({ siteName: obj.siteName, toDate: obj.toDate, p: obj.p }, async function (res) { _this.refresh_table_view({ el: '#site_logs_table', form_id: 'site_logs_table', // 用于重置 config: [ { fid: '0', width: '150px', title: '时间' }, { fid: '1', title: '用户 IP', tips: true, width: '120px', type: 'link', templet: function (row, index) { var ip = row[1]; var ipLocation = row[8]; return '<a class="btlink add_log_ip_black" title="' + _this.escapeHTML(ipLocation) + '" data-cityip="' + _this.escapeHTML(ipLocation) + '" data-ip="' + _this.escapeHTML(ip) + '" >' + _this.escapeHTML(ip) + '</a>'; } }, { fid: '2', title: '类型' }, { fid: '3', title: 'URL 地址', templet: function (row, index) { return '<span title="' + _this.escapeHTML(row[3]) + '">' + _this.escapeHTML(row[3]) + '</span>' } }, { title: '状态', templet: function (row, index) { return '已拦截'; } }, { fid: '5', title: '过滤器', tips: true, width: '80px' }, { fid: 'tools', title: '操作', width: '125px', style: 'text-align: right;', group: [ { title: '误报', event: function (row, index) { layer.confirm('是否确定提交误报反馈?', { title: '误报反馈', closeBtn: 2, icon: 3 }, function () { var rule_arry = row[6].split(" >> "); _this.add_url_white({ url_rule: row[3] }, function (res) { layer.msg(res.msg, { icon: 1 }); if (rule_arry[1] != undefined) { $.get('https://www.bt.cn/Api/add_waf_logs?data=' + rule_arry[1], function (rdata) { }, 'jsonp') } }); }); } }, { title: '详细', event: function (row, index) { var filter_rule = '', rule_arry = row[6].split(" >> "), incoming_value = '', risk_value = ''; if (rule_arry.length == 0) filter_rule = rule_arry[0] incoming_value = rule_arry[1] == undefined? '空' : rule_arry[1]; risk_value = incoming_value.match(new RegExp(rule_arry[0].replace(/\//g, '\\/'), 'i')); risk_value = risk_value? risk_value[0] : '空'; layer.open({ type: 1, title: "【" + row[0] + "】详情", area: '600px', closeBtn: 2, shadeClose: false, content: '<div class="pd15 lib-box">\ <table class="table" style="border:#ddd 1px solid; margin-bottom:10px">\ <tbody><tr><th>时间</th><td>' + _this.escapeHTML(row[0]) + '</td><th>用户 IP</th><td><a class="btlink add_log_ip_black" title="加入黑名单">' + _this.escapeHTML(row[1]) + '</a></td><th>类型</th><td>' + _this.escapeHTML(row[2]) + '</td></tr><tr><th>过滤器</th><td>' + _this.escapeHTML(row[5]) + '</td><th>IP归属地</th><td>' + _this.escapeHTML(row[8]) + '</td><th></th><td></td></tr></tbody></table>\ <div><b style="margin-left:10px">URI 地址</b></div>\ <div class="lib-con pull-left mt10"><div class="divpre">' + _this.escapeHTML(row[3]) + '</div></div>\ <div><b style="margin-left:10px">User-Agent</b></div>\ <div class="lib-con pull-left mt10"><div class="divpre">' + _this.escapeHTML(row[4]) + '</div></div>\ <div><b style="margin-left:10px">过滤规则</b></div>\ <div class="lib-con pull-left mt10"><div class="divpre">' + _this.escapeHTML(rule_arry[0]) + '</div></div>\ <div><b style="margin-left:10px">传入值</b></div>\ <div class="lib-con pull-left mt10"><div class="divpre">' + _this.escapeHTML(incoming_value) + '</div></div>\ <div><b style="margin-left:10px">风险值</b></div>\ <div class="lib-con pull-left mt10"><div class="divpre">' + _this.escapeHTML(risk_value) + '</div></div>\ </div>', success: function () { $('.add_log_ip_black').click(function () { layer.confirm('是否将 <span style="color:red">' + row[1] + '</span> 添加到 IP 黑名单?', { title: '加入 IP 黑名单', closeBtn: 2 }, function () { _this.add_ip_black({ start_ip: row[1], end_ip: row[1] }, function (res) { layer.msg(res.msg, { icon: res.status? 1 : 2 }); }); }); }); } }) } }, { title: 'HTTP', event: function (row, index) { var _http_info = row[7]; if (_http_info) { layer.open({ type: 1, title: "【" + row[0] + "】HTTP 详情", area: ['800px', '500px'], closeBtn: 1, shadeClose: false, maxmin: true, content: '<div class="pd15 lib-box" style="height:100%">\ <pre id="http_info_data" style="height:100%"></pre></div>', success: function (layers) { $('#http_info_data').text(_http_info); $(layers).css('top', ($(window).height() - $(layers).height()) / 2); } }) } else { layer.msg('暂无 HTTP 详情信息', { icon: 6 }) } } } ] } ], data: res, done: function (res) { $('.site_logs_page').html(_this.render_logs_pages(9, obj.p, res.length)); $('.site_logs_page a').unbind().click(function (e) { var _page = parseInt($(this).attr('data-page')); _this.render_site_logs({ siteName: obj.siteName, toDate: obj.toDate, p: _page }); }); // 使用事件委托绑定点击事件 $('#site_logs_table').on('click', '.add_log_ip_black', function () { var ip = $(this).data('ip');var cityip = $(this).data('cityip'); layer.confirm('是否将 <span style="color:red">' + ip + '</span> 添加到 IP 黑名单?<br>来自:' + cityip + '', { title: '加入 IP 黑名单', closeBtn: 2, icon: 0 }, function () { _this.add_ip_black({ start_ip: ip, end_ip: ip }, function (res) { layer.msg(res.msg, { icon: res.status? 1 : 2 }); }); }); }); } }); }); },
复制代码 渲染效果如楼上的截屏。 |