免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3484 | 回复: 3
打印 上一主题 下一主题

[文本处理] 用awk分析处理nginx的日志的一种思路 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2014-07-05 13:16 |只看该作者 |倒序浏览
本帖最后由 UltimateSniper 于 2014-07-05 13:17 编辑

因为最近搭建了一个blog,所以会想到一个问题,如何屏蔽别人的恶意扫描,在网上也找了不少相关资料,然后根据自己的实践,最后想了一个思路,但是还不完善,所以希望能提出来让大家帮忙讨论一下,而且因为对awk还不够熟练,有几个问题暂时还没解决,希望高手能帮帮忙。

nginx日志的log_format如下:
  1. log_format  access  '$remote_addr - $remote_user [$time_local] "$request" '
  2.              '$status $body_bytes_sent "$http_referer" '
  3.              '"$http_user_agent" $http_x_forwarded_for';
复制代码
具体日志差不多就是下面这样:
180.153.197.58 - - [05/Jul/2014:12:16:05 +0800] "HEAD /blog/ HTTP/1.1" 200 0 "-" "Mozilla/5.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 1.1.4322) Jiankongbao" -

以空格作为分隔符的话,第1列为访问者IP,第9列为HTTP状态码。

处理思路就是:监控nginx的访问日志,将请求出错(例如频繁的 404 错误,明显是扫描)的访问者 IP 放入一个 List 特别观察,在一段时间内如果没有太多的出错,我们就将其从列表中移除,否则,错误太多达到警戒值就调用 iptable 将其禁封。

大概的脚本结构就是:
  1. log_file = "/path/to/access.log"
  2. error_block = 10
  3. expire_time = 7200

  4. # tail --follow=$log_file #用tail的--follow选项据说可以有效轮询提高效率,求大牛解答

  5. while read line
  6. do
  7.         if(echo $line | grep ' 404 ')
  8.         then
  9.         # 记录下访问者IP(同时建立起一个数组用于分别计数,当次数达到某个阈值时就封禁它的IP)
  10.         fi
  11. done < $log_file
复制代码
我觉得在while循环里面直接全用awk来处理的话效果会比if判断结构要好,所以请各位能给出些思路或awk方面处理的指导,谢谢了。

论坛徽章:
0
2 [报告]
发表于 2014-07-05 14:58 |只看该作者
本帖最后由 zerostudy 于 2014-07-05 15:29 编辑

想问下:
1、这个日志每天或多少天会切割?
2、当次数达到某个阈值时就封禁它的IP,这个次数从当前日志中的所有累加?
还是检测时间间隔的的次数。
比如:10点钟检测一次(从日志文件开头到当前时间),a的ip404的有3次,那么在12点再检测一次,这时a的ip是要从日志的开头开始,还是从10点到12点这段时间的a访问4o4的次数?




=>又看了下题,原来是要检测时间内的变化。

论坛徽章:
0
3 [报告]
发表于 2014-07-05 15:39 |只看该作者
的访问者 IP 放入一个 List 特别观察,在一段时间内如果没有太多的出错,我们就将其从列表中移除,否则,错误太多达到警戒值就调用 iptable 将其禁封。

下面的代码总是感觉和题意不相同,不过写出来了,我也就贴出来,大家不要笑。

下面超过5次的就直接drop掉了。
  1. #! /bin/sh
  2. fileout="out404ip"

  3. if [ -f "$fileout" ];then
  4.         lasttime=`tail -1 $fileout`
  5.         echo $lasttime
  6.         awk -v tmprq=$lasttime  '{

  7.         if($4 == tmprq)
  8.                 {
  9.                         row=NR;
  10.                         while(getline <"2")
  11.                                 {
  12.                                         ++i;
  13.                                         FS=" ";
  14.                                         if(i>=row)
  15.                                         {
  16.                                                 b[$1]++;
  17.                                                 rq=$4;
  18.                                         };
  19.                                 };
  20.                         for(x in b)
  21.                         {
  22.                             print x,b[x] > "out";

  23.                         }
  24.                         print rq>> "out";
  25.                 };
  26.                                         }' 2

  27.         cat out > out404ip

  28.         sed '$d' out | awk '{if ($2 > 5){system("iptables -A INPUT -s "$1" -j DROP")}}'


  29. else

  30.         awk '/ 404 /{a[$1]++;rq=$4}END{for(x in a){print x,a[x] > "out404ip" };print rq >> "out404ip"}' 2
  31.         sed '$d' out404ip | awk '{if ($2 > 5){system("iptables -A INPUT -s "$1" -j DROP")}}'

  32. fi
复制代码

论坛徽章:
0
4 [报告]
发表于 2014-07-05 23:38 |只看该作者
回复 3# zerostudy


    下午有事去了没有及时看帖子,不好意思哈。

一时没法测试你的脚本,等时间空出来了我再读一读你的脚本,然后实际测试一下,先谢谢你的帮忙了。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP