我有一个修改过的日志文件,列出了访问我的服务器的所有IP地址。
每行IP地址旁边是一个日期/时间戳。
在我寻求过滤机器人和恶意活动时,我想检查一下是否有任何IP地址在15秒内发出了超过5个请求。
我已经发布了一篇关于如何从第一次请求中度量这个问题的问题,但是我想进一步了解这一点。
我目前正在学习AWK,我想了解更多。如果可能的话,I希望在(G)AWK中完成这一任务,并尽可能明确地解释,这样我就可以研究这个脚本,并希望在将来能够自己编写类似的脚本。
虽然我知道这很可能是用Python完成的,但我目前还没有学习Python。
下面是我的日志文件的完整(工作)修改版本(用于混淆IP地址):log-file.csv。
下面是该文件的一个示例,以防您更愿意对照该文件测试结果:
03/Nov/2020:06:33:09|000.000.000.001|200|/page-1/
03/Nov/2020:07:12:21|000.000.000.002|200|/page-2/
03/Nov/2020:07:24:52|000.000.000.003|200|/page-3/
03/Nov/2020:07:30:50|000.000.000.004|200|/page-4/
03/Nov/2020:07:47:29|000.000.000.005|200|/page-5/
03/Nov/2020:07:52:42|000.000.000.006|200|/page-6/
03/Nov/2020:07:52:55|000.000.000.007|200|/page-7/
03/Nov/2020:08:00:11|000.000.000.008|200|/page-8/
03/Nov/2020:08:05:00|000.000.000.009|200|/page-9/
03/Nov/2020:08:05:06|000.000.000.010|301|/page-10/
03/Nov/2020:08:05:32|000.000.000.007|200|/page-11/
03/Nov/2020:09:02:49|000.000.000.011|304|/page-12/
03/Nov/2020:09:02:49|000.000.000.011|404|/page-13/
03/Nov/2020:09:13:18|000.000.000.011|304|/page-14/
03/Nov/2020:09:13:19|000.000.000.011|404|/page-15/
03/Nov/2020:09:14:20|000.000.000.012|200|/page-16/
03/Nov/2020:09:23:48|000.000.000.011|304|/page-17/
03/Nov/2020:09:23:49|000.000.000.011|404|/page-18/
03/Nov/2020:09:34:19|000.000.000.011|304|/page-19/
03/Nov/2020:09:34:19|000.000.000.011|404|/page-20/
03/Nov/2020:09:35:42|000.000.000.013|301|/page-21/
03/Nov/2020:09:35:42|000.000.000.013|404|/page-22/
03/Nov/2020:09:44:49|000.000.000.011|304|/page-23/
03/Nov/2020:09:44:49|000.000.000.011|404|/page-24/
03/Nov/2020:09:53:38|000.000.000.014|200|/page-25/
03/Nov/2020:09:55:19|000.000.000.011|304|/page-26/
03/Nov/2020:09:55:19|000.000.000.011|404|/page-27/
03/Nov/2020:10:05:49|000.000.000.011|304|/page-28/
03/Nov/2020:10:05:49|000.000.000.011|404|/page-29/
03/Nov/2020:10:06:27|000.000.000.005|200|/page-30/
03/Nov/2020:10:16:19|000.000.000.011|304|/page-31/
03/Nov/2020:10:16:19|000.000.000.011|404|/page-32/
03/Nov/2020:10:17:21|000.000.000.015|200|/page-33/
03/Nov/2020:10:20:35|000.000.000.016|200|/page-34/
03/Nov/2020:10:20:37|000.000.000.017|404|/page-35/
03/Nov/2020:10:20:42|000.000.000.017|404|/page-39/
03/Nov/2020:10:20:49|000.000.000.016|200|/page-40/
03/Nov/2020:10:20:55|000.000.000.017|404|/page-41/
03/Nov/2020:10:21:01|000.000.000.017|404|/page-42/
03/Nov/2020:10:21:03|000.000.000.017|404|/page-43/
03/Nov/2020:10:21:05|000.000.000.017|404|/page-44/
03/Nov/2020:10:21:06|000.000.000.017|404|/page-45/
03/Nov/2020:10:21:11|000.000.000.017|404|/page-46/
03/Nov/2020:10:21:14|000.000.000.016|200|/page-47/
03/Nov/2020:10:21:34|000.000.000.016|200|/page-48/
03/Nov/2020:10:21:47|000.000.000.016|200|/page-49/
03/Nov/2020:10:22:14|000.000.000.016|200|/page-50/
03/Nov/2020:10:22:15|000.000.000.016|200|/page-51/
03/Nov/2020:10:22:15|000.000.000.016|200|/page-52/
03/Nov/2020:10:22:16|000.000.000.016|200|/page-52/
03/Nov/2020:10:22:17|000.000.000.016|200|/page-53/
03/Nov/2020:10:22:18|000.000.000.019|200|/page-1/
03/Nov/2020:10:22:20|000.000.000.016|200|/page-55/
03/Nov/2020:10:22:20|000.000.000.016|200|/page-56/我希望您生成一个名为bot-list.txt的文档,其中包含在任何时候(不一定是前5个)在15秒内发出5个或更多请求的IP地址列表。我可能希望在稍后的日期调整频率/持续时间。
因为日志文件很大,所以我觉得在这里发布整个日志文件是不合适的。但是,上面(修改的)示例的输出只有两个IP地址。因此,测试完整的日志文件将更加可靠。
000.000.000.017
000.000.000.016<#>Please要明确说明如何实现结果。作为额外的奖励,如果你确实使用任何模糊的技术/功能,我很高兴你能指出一个参考,我可以了解更多关于这项技术。
log-file.csv中搜索每个唯一的IPbot-list.txt。欢迎就如何改进这一概念提出进一步建议。
老实说,我不知道如何比较GAWK中的行,但从我前面问题中的一些答案可以清楚地看出,这是可能的。
目前,我正在阅读“有效的AWK编程”一书。这是很有趣的,但我挣扎于其中的一些。我也在研究关联数组,但是由于我不是来自编程背景,所以我正在慢慢地学习这些知识。
我找不到任何能解决我的具体问题的东西,关于这个问题的视频也很少。
如果有人能指出可以帮助我解决这样的问题的有用资源,我会感激的。
My尝试比较日期:
egrep "000.111.000.111" log-file.csv | awk 'BEGIN{FS="|"; ORS=" "} NR==1 || NR==5 {print $1,$2}' | sed -e 's/[\/:]/\ /g' -e 's/Jan/1/g' -e 's/Feb/2/g' -e 's/Mar/3/g' -e 's/Apr/4/g' -e 's/May/5/g' -e 's/Jun/6/g' -e 's/Jul/7/g' -e 's/Aug/8/g' -e 's/Sep/9/g' -e 's/Oct/10/g' -e 's/Nov/11/g' -e 's/Dec/12/g' | awk '{print $3,$2,$1,$4,$5,$6 "," $10,$9,$8,$11,$12,$13","$14}' | awk -F, '{d2=mktime($2);d1=mktime($1);print d2-d1, $3}' | awk '{if($1<15)print $2}' >> bot-list.txt不幸的是,正如您所看到的,我无法在(G)AWK中完成全部工作,但如果您可以的话,我将不胜感激。
(这是我第二次使用。我曾尝试遵从有关如何提出我的问题的意见,如果我有任何错误,我很高兴收到进一步的意见)。
谢谢。
发布于 2020-11-04 22:03:33
一种简单的、蛮力的方法,将所有IP地址和时间戳转换为将秒转换为内存( secs[]数组),然后在读取完整个文件后,每次遍历一个IP地址,每5个条目查看时间戳之间的差异,看看是否有小于15秒的时间戳:
$ cat tst.awk
BEGIN { FS="|" }
{
split($1,t,"[/:]")
monthNr = (index("JanFebMarAprMayJunJulAugSepOctNovDec",t[2])+2)/3
currSecs = mktime(t[3] " " monthNr " " t[1] " " t[4] " " t[5] " " t[6])
secs[$2][++count[$2]] = currSecs
}
END {
range = 5
for (ip in secs) {
for (beg=1; beg<=(count[ip]-range)+1; beg++) {
end = beg + range - 1
if ( (secs[ip][end] - secs[ip][beg]) < 15 ) {
print ip
break
}
}
}
}$ awk -f tst.awk file
000.000.000.016
000.000.000.017这确实意味着您需要有足够的内存来存储IP地址列表和时间秒,但是要想成为一个问题,您的文件必须是巨大的(数十亿行)。
编辑:根据您问题下面的注释,您的输入文件没有按照正确的顺序(递增date+time),因此我们可以这样做来修复这个问题:
$ awk -F'|' '
{
split($1,t,"[/:]")
monthNr = (index("JanFebMarAprMayJunJulAugSepOctNovDec",t[2])+2)/3
currSecs = mktime(t[3] " " monthNr " " t[1] " " t[4] " " t[5] " " t[6])
print currSecs, NR, $0
}
' log-file.csv | sort -k1,1n -k2,2n | cut -d' ' -f3- > sorted-log-file.csv然后运行上面的脚本,以获得以下50个IP地址输出:
$ awk -f tst.awk sorted-log-file.csv | sort
000.000.000.011
000.000.000.017
000.000.000.036
000.000.000.056
000.000.000.066
000.000.000.094
000.000.000.115
000.000.000.121
000.000.000.136
000.000.000.141
000.000.000.157
000.000.000.169
000.000.000.178
000.000.000.181
000.000.000.183
000.000.000.208
000.000.000.227
000.000.000.230
000.000.000.283
000.000.000.312
000.000.000.354
000.000.000.361
000.000.000.368
000.000.000.370
000.000.000.505
000.000.000.515
000.000.000.579
000.000.000.580
000.000.000.588
000.000.000.610
000.000.000.634
000.000.000.642
000.000.000.651
000.000.000.748
000.000.000.756
000.000.000.758
000.000.000.772
000.000.000.795
000.000.000.814
000.000.000.852
000.000.000.878
000.000.000.882
000.000.000.922
000.000.000.994
000.000.000.995
000.000.001.047
000.000.001.119
000.000.001.139
000.000.001.185
000.000.001.198https://unix.stackexchange.com/questions/618038
复制相似问题