分享
  • 收藏
  • 举报
    X
    让宝塔Nginx免费防火墙显示IP归属地城市名
    70
    0

    小伙伴们都知道宝塔Nginx免费防火墙挺好用的哈。唯一的就是IP地址没有归属地,总感觉有些不舒服。幸运的小编做AI即时通讯聊天室有提供这个IP物理地址的接口的哈,废话不多说下面进入主题。找到(/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('&amp;', '&').replace('&lt;', 

                                                                                                         '<').replace( 

                                                '&gt;', '>') 

                                        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 

    全部修改完成,因为小编没有办法访问下载City.mmdb,所以也只能用文韵坊阅读网IP归属地接口。能下载的改下那个IP归属地的方法即可。效果图如下:


    看到了吧。是不是日志输出的JSON里面有IP归属地物理地址了。至于怎么渲染出来,自行修改/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(" &gt;&gt; "); 

                                _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(" &amp;gt;&amp;gt; "), 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 }); 

                        }); 

                    }); 

                }); 

            } 

        }); 

    }); 

    }, 

    // 渲染封锁历史列表 

    render_history_data:function(obj,callback){ 

        var _this = this; 

        if(obj == undefined) obj={p:1} 

        this.get_safe_logs_ip({p:obj.p},function(res){ 

            _this.refresh_table_view({ 

                el:'#history_table', 

                form_id:'history_table', //用于重置 

                config:[ 

                    {fid:'0',title:'开始时间',type:'link',templet:function(res){return bt.format_data(res[0])}}, 

                    {fid:'1',title:'IP',templet:function(row,index){ 

                              return row[7]?'<a href="javascript:;" class="btlink uncover_ip" title="解封当前IP('+row[1]+':'+ row[6] +')" data-ip="'+ row[1] +'">'+ row[1] +'</a>':'<span title="' + row[6] + '">' + row[1] + '</span>'; 

                    }}, 

                    {fid:'2',title:'站点'}, 

                    {fid:'3',title:'封锁原因',templet:function(row,index){ 

                        return row[5] === 'cc'?'CC攻击':'多次恶意请求'; 

                    }}, 

                    {fid:'4',title:'封锁时长',templet:function(row,index){ 

                        return row[4] + '秒'; 

                    }}, 

                    {fid:'5',title:'状态',style:'text-align: right;',templet:function(row,index){ 

                        return row[7]?'<span style="color:red">封锁中</span>':'已解封'; 

                    }} 

                ], 

                data:res, 

                done:function(res){ 

                    // 解封所有封锁 

                    $('.uncover_ip').click(function(){ 

                        var _ip = $(this).attr('data-ip'); 

                        var _cityip = $(this).attr('data-cityip'); 

                        layer.confirm('是否要从防火墙解封IP【'+ _ip +':'+ _cityip +'】', { title: '解封IP地址',closeBtn:2,icon:0}, function () { 

                            _this.remove_waf_drop_ip({ip:_ip},function(res){ 

                                _this.render_history_data(); 

                                layer.msg(res.msg,{icon:res.status?1:2}); 

                            }); 

                        }); 

                    }); 

                    $('.history_uncover_page').html(_this.render_logs_pages(10,obj.p,res.length)); 

                    $('.history_uncover_page a').unbind().click(function(e){ 

                        var _page = parseInt($(this).attr('data-page')); 

                        _this.render_history_data({p:_page}); 

                    }); 

                    if(callback) callback(res) 

                } 

            }) 

        }); 

    }, 

    既然小编都提到宝塔Nginx免费防火墙了,那就把小编屏蔽的垃圾爬虫规则也说下吧。User-Agent过滤(通常用于过滤浏览器、蜘蛛及一些自动扫描器)

    (Amazonbot|GPTBot|CheckMarkNetwork|Synapse|Nimbostratus-Bot|Dark|scraper|LMAO|Hakai|Gemini|Wappalyzer|masscan|crawler4j|Mappy|Center|eright|aiohttp|MauiBot|Crawler|researchscan|Dispatch|AlphaBot|Census|ips-agent|NetcraftSurveyAgent|ToutiaoSpider|EasyHttp|Iframely|sysscan|fasthttp|muhstik|DeuSu|mstshash|HTTP_Request|ExtLink***ot|package|SafeDN***ot|CPython|SiteExplorer|SSH|MegaIndex|BUbiNG|CCBot|NetTrack|Digincore|aiHitBot|SurdotlyBot|null|SemrushBot|Test|Copied|ltx71|Nmap|DotBot|Ad***ot|InetURL|Pcore-HTTP|PocketParser|Wotbox|newspaper|DnyzBot|redback|PiplBot|SMTBot|WinHTTP|Auto Spider 1.0|GrabNet|TurnitinBot|Go-Ahead-Got-It|Download Demon|Go!Zilla|GetWeb!|GetRight|libwww-perl|Cliqzbot|MailChimp|SMTBot|Dataprovider|XoviBot|linkdexbot|SeznamBot|Qwantify|spbot|evc-batch|zgrab|Go-http-client|FeedDemon|JikeSpider|Indy Library|Alexa Toolbar|AskTbFXTV|Ahref***ot|CrawlDaddy|CoolpadWebkit|Java|UniversalFeedParser|ApacheBench|Microsoft URL Control|Swiftbot|ZmEu|jaunty|Python-urllib|lightDeckReports Bot|YYSpider|DigExt|YisouSpider|HttpClient|MJ12bot|EasouSpider|LinkpadBot|Ezooms|ClaudeBot) 


     《让宝塔Nginx免费防火墙显示IP归属地城市名》首发文韵坊阅读网,推荐你来看看,原文地址: https://www.wenyunfang.com/zazhi/zhongwangjiaocheng/1273.html


    2
    赏礼
    赏钱
    收藏
    点击回复
        全部留言
    • 0
    更多回复
        你可能感兴趣的主题
    恢复多功能编辑器
  • 3 1
  • 推荐内容
    扫一扫访问手机版
    请选择要切换的马甲:

     
    网页即时交流
    QQ咨询
    咨询热线
    020-28998648