逝水年华 发表于 2025-3-22 21:57:02

让宝塔Nginx免费防火墙显示IP归属地城市名

***内容可能违规暂时被隐藏***

Crystαl 发表于 2025-3-22 21:57:57

少折腾吧 花钱买专业版就是了

拾光 发表于 2025-3-22 21:58:34

这个可以

婷姐 发表于 2025-3-22 21:58:46


这样不是更为直观吗?比数字好吧。

IT618发布 发表于 2025-3-22 21:59:26

找到(/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         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                         if line:                           try:                                 tmp_data = json.loads(cgi.escape(line))                                 for i in range(len(tmp_data)):                                     if i == 7:                                       tmp_data = str(tmp_data).replace('&', '&').replace('<',                                                                                                      '<').replace(                                             '>', '>')                                     else:                                       tmp_data = cgi.escape(str(tmp_data), True)                                 ip = tmp_data                                 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)) < float(data) and not data in setss:                     setss.append(data)                     data.append(data in drop_iplist)               else:                     data.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;                        var ipLocation = row;                        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) + '">' + _this.escapeHTML(row) + '</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.split(" >> ");                              _this.add_url_white({ url_rule: row }, function (res) {                                    layer.msg(res.msg, { icon: 1 });                                    if (rule_arry != undefined) { $.get('https://www.bt.cn/Api/add_waf_logs?data=' + rule_arry, function (rdata) { }, 'jsonp') }                              });                            });                        }                  },                  {                        title: '详细',                        event: function (row, index) {                            var filter_rule = '', rule_arry = row.split(" >> "), incoming_value = '', risk_value = '';                            if (rule_arry.length == 0) filter_rule = rule_arry                            incoming_value = rule_arry == undefined? '空' : rule_arry;                            risk_value = incoming_value.match(new RegExp(rule_arry.replace(/\//g, '\\/'), 'i'));                            risk_value = risk_value? risk_value : '空';                            layer.open({                              type: 1,                              title: "【" + row + "】详情",                              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) + '</td><th>用户 IP</th><td><a class="btlink add_log_ip_black"title="加入黑名单">' + _this.escapeHTML(row) + '</a></td><th>类型</th><td>' + _this.escapeHTML(row) + '</td></tr><tr><th>过滤器</th><td>' + _this.escapeHTML(row) + '</td><th>IP归属地</th><td>' + _this.escapeHTML(row) + '</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) + '</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) + '</div></div>\                                        <div><b style="margin-left:10px">过滤规则</b></div>\                                        <div class="lib-con pull-left mt10"><div class="divpre">' + _this.escapeHTML(rule_arry) + '</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 + '</span> 添加到 IP 黑名单?', { title: '加入 IP 黑名单', closeBtn: 2 }, function () {                                          _this.add_ip_black({ start_ip: row, end_ip: row }, function (res) {                                                layer.msg(res.msg, { icon: res.status? 1 : 2 });                                          });                                        });                                    });                              }                            })                        }                  },                  {                        title: 'HTTP',                        event: function (row, index) {                            var _http_info = row;                            if (_http_info) {                              layer.open({                                    type: 1,                                    title: "【" + row + "】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 });                        });                  });                });            }      });    });    },渲染效果如楼上的截屏。

独家记忆 发表于 2025-3-22 21:59:40

现在专业版真不贵

Crystαl 发表于 2025-3-22 22:00:06

699 元/年 说贵也不贵哈。只是给需要而又懒的人吧。

IT618发布 发表于 2025-3-22 22:00:20

主要发个帖子还可以领取1000金币这是最最主要的

婷姐 发表于 2025-3-22 22:01:12

可以接入纯真ip库呀

拾光 发表于 2025-3-22 22:01:52

我的php接口就是接入的纯真IP库的。都有现成的接口我直接CURL更好
页: [1]
查看完整版本: 让宝塔Nginx免费防火墙显示IP归属地城市名