技术文摘

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

作者:雨祺   发表于:
浏览:84次    字数:11624  电脑原创
级别:站长   总稿:79篇, 月稿:10
小伙伴们都知道宝塔Nginx免费防火墙挺好用的哈。唯一的就是IP地址没有归属地,总感觉有些不舒服。幸运的小编做AI即时通讯聊天室有提供这个IP物理地址的接口的哈,废话不多说下面进入主题。找到(/www/server/panel/plugin/free_waf/free_waf_main.py)这个文件
给这个类增加一个IP归属地显示的方法。代码如下(17行下面):
  1. def getIpLocation(self, ip): 
  2.     url = f"https://www.wenyunfang.com/e/extend/chat/info.php?enews=ipcha&ip={ip}" 
  3.     try
  4.         response = requests.get(url) 
  5.         if response.status_code == 200: 
  6.             data = response.json() 
  7.             if data["code"] == 1: 
  8.                 location = data["ip2"
  9.                 return location 
  10.             else
  11.                 return "查询失败,错误代码: " + str(data["code"]) 
  12.         else
  13.             return f"请求失败,状态码: {response.status_code}" 
那我们在日志获取方法的类新增IP归属地显示。仍然是这个文件。(get_safe_logs)为方法,直接贴方法了哈
  1. def get_safe_logs(self, get): 
  2.     try
  3.         import cgi 
  4.         pythonV = sys.version_info[0] 
  5.         if 'drop_ip' in get: 
  6.             path = '/www/server/free_waf/drop_ip.log' 
  7.             num = 14 
  8.         else
  9.             path = '/www/wwwlogs/free_waf_log/' + get.siteName + '_' + get.toDate + '.log' 
  10.             num = 10 
  11.         if not os.path.exists(path): return [] 
  12.         p = 1 
  13.         if 'p' in get: 
  14.             p = int(get.p) 
  15.         start_line = (p - 1) * num 
  16.         count = start_line + num 
  17.         fp = open(path, 'rb'
  18.         buf = "" 
  19.         try
  20.             fp.seek(-1, 2) 
  21.         except: 
  22.             return [] 
  23.         if fp.read(1) == "\n": fp.seek(-1, 2) 
  24.         data = [] 
  25.         b = True 
  26.         n = 0 
  27.         c = 0 
  28.         while c < count: 
  29.             while True: 
  30.                 newline_pos = str.rfind(buf, "\n"
  31.                 pos = fp.tell() 
  32.                 if newline_pos != -1: 
  33.                     if n >= start_line: 
  34.                         line = buf[newline_pos + 1:] 
  35.                         if line: 
  36.                             try
  37.                                 tmp_data = json.loads(cgi.escape(line)) 
  38.                                 for i in range(len(tmp_data)): 
  39.                                     if i == 7: 
  40.                                         tmp_data[i] = str(tmp_data[i]).replace('&amp;''&').replace('&lt;'
  41.                                                                                                      '<').replace( 
  42.                                             '&gt;''>'
  43.                                     else
  44.                                         tmp_data[i] = cgi.escape(str(tmp_data[i]), True) 
  45.                                 ip = tmp_data[1] 
  46.                                 ip_location = self.getIpLocation(ip) 
  47.                                 tmp_data.append(ip_location) 
  48.                                 data.append(tmp_data) 
  49.                             except: 
  50.                                 c -= 1 
  51.                                 n -= 1 
  52.                                 pass 
  53.                         else
  54.                             c -= 1 
  55.                             n -= 1 
  56.                     buf = buf[:newline_pos] 
  57.                     n += 1 
  58.                     c += 1 
  59.                     break 
  60.                 else
  61.                     if pos == 0: 
  62.                         b = False 
  63.                         break 
  64.                     to_read = min(4096, pos) 
  65.                     fp.seek(-to_read, 1) 
  66.                     t_buf = fp.read(to_read) 
  67.                     if pythonV == 3: t_buf = t_buf.decode('utf-8', errors="ignore"
  68.                     buf = t_buf + buf 
  69.                     fp.seek(-to_read, 1) 
  70.                     if pos - to_read == 0: 
  71.                         buf = "\n" + buf 
  72.             if not b: break 
  73.         fp.close() 
  74.         if 'drop_ip' in get: 
  75.             drop_iplist = self.get_waf_drop_ip(None) 
  76.             stime = time.time() 
  77.             setss = [] 
  78.             for i in range(len(data)): 
  79.                 if (float(stime) - float(data[i][0])) < float(data[i][4]) and not data[i][1] in setss: 
  80.                     setss.append(data[i][1]) 
  81.                     data[i].append(data[i][1] in drop_iplist) 
  82.                 else
  83.                     data[i].append(False) 
  84.     except: 
  85.         return public.get_error_info() 
  86.         data = [] 
  87.     return data 
全部修改完成,因为小编没有办法访问下载City.mmdb,所以也只能用文韵坊阅读网IP归属地接口。能下载的改下那个IP归属地的方法即可。效果图如下:

看到了吧。是不是日志输出的JSON里面有IP归属地物理地址了。至于怎么渲染出来,自行修改/www/server/panel/plugin/free_waf/index.html 里面那段render_site_logs,比如小编的
  1. // 渲染站点日志 
  2. render_site_logs: function (obj, callback) { 
  3. var _this = this
  4. this.get_safe_logs({ siteName: obj.siteName, toDate: obj.toDate, p: obj.p }, async function (res) { 
  5.     _this.refresh_table_view({ 
  6.         el: '#site_logs_table'
  7.         form_id: 'site_logs_table'// 用于重置 
  8.         config: [ 
  9.             { fid: '0', width: '150px', title: '时间' }, 
  10.             { fid: '1', title: '用户 IP', tips: true, width: '120px', type: 'link'
  11.                 templet: function (row, index) { 
  12.                     var ip = row[1]; 
  13.                     var ipLocation = row[8]; 
  14.                     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>'
  15.                 } 
  16.             }, 
  17.             { fid: '2', title: '类型' }, 
  18.             { fid: '3', title: 'URL 地址', templet: function (row, index) { return '<span title="' + _this.escapeHTML(row[3]) + '">' + _this.escapeHTML(row[3]) + '</span>' } }, 
  19.             { title: '状态', templet: function (row, index) { return '已拦截'; } }, 
  20.             { fid: '5', title: '过滤器', tips: true, width: '80px' }, 
  21.             { fid: 'tools', title: '操作', width: '125px', style: 'text-align: right;', group: [ 
  22.                 { 
  23.                     title: '误报'
  24.                     event: function (row, index) { 
  25.                         layer.confirm('是否确定提交误报反馈?', { title: '误报反馈', closeBtn: 2, icon: 3 }, function () { 
  26.                             var rule_arry = row[6].split(" &gt;&gt; "); 
  27.                             _this.add_url_white({ url_rule: row[3] }, function (res) { 
  28.                                 layer.msg(res.msg, { icon: 1 }); 
  29.                                 if (rule_arry[1] != undefined) { $.get('https://www.bt.cn/Api/add_waf_logs?data=' + rule_arry[1], function (rdata) { }, 'jsonp') } 
  30.                             }); 
  31.                         }); 
  32.                     } 
  33.                 }, 
  34.                 { 
  35.                     title: '详细'
  36.                     event: function (row, index) { 
  37.                         var filter_rule = '', rule_arry = row[6].split(" &amp;gt;&amp;gt; "), incoming_value = '', risk_value = ''
  38.                         if (rule_arry.length == 0) filter_rule = rule_arry[0] 
  39.                         incoming_value = rule_arry[1] == undefined? '空' : rule_arry[1]; 
  40.                         risk_value = incoming_value.match(new RegExp(rule_arry[0].replace(/\//g, '\\/'), 'i')); 
  41.                         risk_value = risk_value? risk_value[0] : '空'
  42.                         layer.open({ 
  43.                             type: 1, 
  44.                             title: "【" + row[0] + "】详情"
  45.                             area: '600px'
  46.                             closeBtn: 2, 
  47.                             shadeClose: false
  48.                             content: '<div class="pd15 lib-box">\ 
  49.                                     <table class="table" style="border:#ddd 1px solid; margin-bottom:10px">\ 
  50.                                     <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>\ 
  51.                                     <div><b style="margin-left:10px">URI 地址</b></div>\ 
  52.                                     <div class="lib-con pull-left mt10"><div class="divpre">' + _this.escapeHTML(row[3]) + '</div></div>\ 
  53.                                     <div><b style="margin-left:10px">User-Agent</b></div>\ 
  54.                                     <div class="lib-con pull-left mt10"><div class="divpre">' + _this.escapeHTML(row[4]) + '</div></div>\ 
  55.                                     <div><b style="margin-left:10px">过滤规则</b></div>\ 
  56.                                     <div class="lib-con pull-left mt10"><div class="divpre">' + _this.escapeHTML(rule_arry[0]) + '</div></div>\ 
  57.                                     <div><b style="margin-left:10px">传入值</b></div>\ 
  58.                                     <div class="lib-con pull-left mt10"><div class="divpre">' + _this.escapeHTML(incoming_value) + '</div></div>\ 
  59.                                     <div><b style="margin-left:10px">风险值</b></div>\ 
  60.                                     <div class="lib-con pull-left mt10"><div class="divpre">' + _this.escapeHTML(risk_value) + '</div></div>\ 
  61.                                 </div>', 
  62.                             success: function () { 
  63.                                 $('.add_log_ip_black').click(function () { 
  64.                                     layer.confirm('是否将 <span style="color:red">' + row[1] + '</span> 添加到 IP 黑名单?', { title: '加入 IP 黑名单', closeBtn: 2 }, function () { 
  65.                                         _this.add_ip_black({ start_ip: row[1], end_ip: row[1] }, function (res) { 
  66.                                             layer.msg(res.msg, { icon: res.status? 1 : 2 }); 
  67.                                         }); 
  68.                                     }); 
  69.                                 }); 
  70.                             } 
  71.                         }) 
  72.                     } 
  73.                 }, 
  74.                 { 
  75.                     title: 'HTTP'
  76.                     event: function (row, index) { 
  77.                         var _http_info = row[7]; 
  78.                         if (_http_info) { 
  79.                             layer.open({ 
  80.                                 type: 1, 
  81.                                 title: "【" + row[0] + "】HTTP 详情"
  82.                                 area: ['800px''500px'], 
  83.                                 closeBtn: 1, 
  84.                                 shadeClose: false
  85.                                 maxmin: true
  86.                                 content: '<div class="pd15 lib-box" style="height:100%">\ 
  87.                                         <pre id="http_info_data" style="height:100%"></pre></div>', 
  88.                                 success: function (layers) { 
  89.                                     $('#http_info_data').text(_http_info); 
  90.                                     $(layers).css('top', ($(window).height() - $(layers).height()) / 2); 
  91.                                 } 
  92.                             }) 
  93.                         } else { 
  94.                             layer.msg('暂无 HTTP 详情信息', { icon: 6 }) 
  95.                         } 
  96.                     } 
  97.                 } 
  98.             ] } 
  99.         ], 
  100.         data: res, 
  101.         done: function (res) { 
  102.             $('.site_logs_page').html(_this.render_logs_pages(9, obj.p, res.length)); 
  103.             $('.site_logs_page a').unbind().click(function (e) { 
  104.                 var _page = parseInt($(this).attr('data-page')); 
  105.                 _this.render_site_logs({ siteName: obj.siteName, toDate: obj.toDate, p: _page }); 
  106.             }); 
  107.             // 使用事件委托绑定点击事件 
  108.             $('#site_logs_table').on('click''.add_log_ip_black'function () { 
  109.                 var ip = $(this).data('ip');var cityip = $(this).data('cityip'); 
  110.                 layer.confirm('是否将 <span style="color:red">' + ip + '</span> 添加到 IP 黑名单?<br>来自:' + cityip + '', { title: '加入 IP 黑名单', closeBtn: 2, icon: 0 }, function () { 
  111.                     _this.add_ip_black({ start_ip: ip, end_ip: ip }, function (res) { 
  112.                         layer.msg(res.msg, { icon: res.status? 1 : 2 }); 
  113.                     }); 
  114.                 }); 
  115.             }); 
  116.         } 
  117.     }); 
  118. }); 
  119. }, 
  1. // 渲染封锁历史列表 
  2. render_history_data:function(obj,callback){ 
  3.     var _this = this
  4.     if(obj == undefined) obj={p:1} 
  5.     this.get_safe_logs_ip({p:obj.p},function(res){ 
  6.         _this.refresh_table_view({ 
  7.             el:'#history_table'
  8.             form_id:'history_table'//用于重置 
  9.             config:[ 
  10.                 {fid:'0',title:'开始时间',type:'link',templet:function(res){return bt.format_data(res[0])}}, 
  11.                 {fid:'1',title:'IP',templet:function(row,index){ 
  12.                           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>'
  13.                 }}, 
  14.                 {fid:'2',title:'站点'}, 
  15.                 {fid:'3',title:'封锁原因',templet:function(row,index){ 
  16.                     return row[5] === 'cc'?'CC攻击':'多次恶意请求'
  17.                 }}, 
  18.                 {fid:'4',title:'封锁时长',templet:function(row,index){ 
  19.                     return row[4] + '秒'
  20.                 }}, 
  21.                 {fid:'5',title:'状态',style:'text-align: right;',templet:function(row,index){ 
  22.                     return row[7]?'<span style="color:red">封锁中</span>':'已解封'
  23.                 }} 
  24.             ], 
  25.             data:res, 
  26.             done:function(res){ 
  27.                 // 解封所有封锁 
  28.                 $('.uncover_ip').click(function(){ 
  29.                     var _ip = $(this).attr('data-ip'); 
  30.                     var _cityip = $(this).attr('data-cityip'); 
  31.                     layer.confirm('是否要从防火墙解封IP【'+ _ip +':'+ _cityip +'】', { title: '解封IP地址',closeBtn:2,icon:0}, function () { 
  32.                         _this.remove_waf_drop_ip({ip:_ip},function(res){ 
  33.                             _this.render_history_data(); 
  34.                             layer.msg(res.msg,{icon:res.status?1:2}); 
  35.                         }); 
  36.                     }); 
  37.                 }); 
  38.                 $('.history_uncover_page').html(_this.render_logs_pages(10,obj.p,res.length)); 
  39.                 $('.history_uncover_page a').unbind().click(function(e){ 
  40.                     var _page = parseInt($(this).attr('data-page')); 
  41.                     _this.render_history_data({p:_page}); 
  42.                 }); 
  43.                 if(callback) callback(res) 
  44.             } 
  45.         }) 
  46.     }); 
  47. }, 
既然小编都提到宝塔Nginx免费防火墙了,那就把小编屏蔽的垃圾爬虫规则也说下吧。User-Agent过滤(通常用于过滤浏览器、蜘蛛及一些自动扫描器)
  1. (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|ExtLinksBot|package|SafeDNSBot|CPython|SiteExplorer|SSH|MegaIndex|BUbiNG|CCBot|NetTrack|Digincore|aiHitBot|SurdotlyBot|null|SemrushBot|Test|Copied|ltx71|Nmap|DotBot|AdsBot|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|AhrefsBot|CrawlDaddy|CoolpadWebkit|Java|UniversalFeedParser|ApacheBench|Microsoft URL Control|Swiftbot|ZmEu|jaunty|Python-urllib|lightDeckReports Bot|YYSpider|DigExt|YisouSpider|HttpClient|MJ12bot|EasouSpider|LinkpadBot|Ezooms|ClaudeBot) 

【审核人:站长】

99Ai聊天   收藏   加好友   海报   42分享
点赞(0)
打赏
标签:防火墙宝塔

发布者资料

热门文章

技术文摘

查看更多技术文摘
    首页
    栏目
    搜索
    会员
    投稿