我试图用一行命令列出一些有问题的 IP,但不确定如何做最后一点,也许有人可以指出我正确的方向。
cat /var/log/syslog* | grep "SRC=" | cut -d " " -f 14 | sort | uniq -c | sort -n -r
用英语...这应该打印所有系统日志文件(也包括轮换的系统日志文件),搜索防火墙条目并获取 SRC 值(IP),对它们进行计数并从最高到最低列出它们。我现在想要的就是将其限制为前 5 个...有人知道可以做到这一点的命令吗?
系统日志中的示例条目:
Jan 11 12:01:52 xxxx 内核:[47261.722647] 输入数据包失效:IN=eth0 OUT= MAC=44:8a:5b:a0:24:eb:00:31:46:0d:21:e8:08: 00 SRC=xx.xx.xx.xx DST=xx.xx.xx.xx LEN=40 TOS=0x00 PREC=0x00 TTL=239 ID=33840 PROTO=TCP SPT=1024 DPT=22151 WINDOW=1024 RES=0x00 SYN URGP=0
这些条目是由我的自定义防火墙创建的,不是这个问题的一部分
命令的输出示例:
47 SRC=13.82.59.79 2 SRC=77.72.82.145 2 SRC=213.157.51.11 2 SRC=159.203.72.216 1 SRC=77.72.85.15 1 SRC=77.72.85.10 1 SRC=77.72.83.238 1 SRC=77.221.1.237 1 SRC=222.186.172.43 1 SRC=216.170.126.109 1 SRC=191.101.167.253 1 SRC=190.198.183.234 1 SRC=173.254.247.206 1 SRC=164.52.13.58 1 SRC=141.212.122.145 1 SRC=125.78.165.42 1 SRC=118.139.177.119 1 SRC=111.75.222.141 1 SRC=103.30.40.9
答案1
awk '/SRC=/ { print $13 }' /var/log/syslog* | sort | uniq -c | sort -n -r | head -n 5
这消除了原始管道中的 catcat、grelpping 和 cut,并将它们替换为awk
.最后head -n 5
将为您提供前五个结果。
答案2
使用单一 GNUawk
“魔法”:
awk 'BEGIN{
PROCINFO["sorted_in"]="@val_num_desc"
}
/SRC=/{ src[$13]++ }
END{
for (k in src) {
print src[k], k;
if (++c > 4) break
}
}' /var/log/syslog*
答案3
仅使用perl
(不需要grep
、cut
、sort
或uniq
):
perl -lane '
$IPs{$F[12]}++ if (m/SRC=/); # perl arrays start from zero, not 1.
END {
foreach $ip (sort { $IPs{$b} <=> $IPs{$a} } keys %IPs) {
last if ($count++ > 4);
$seen=$IPs{$ip}; # $seen is only really needed in case you uncomment
# the next line, to use the key before we change it.
#$ip =~ s/^SRC=//; # uncomment if you want IPs without the SRC=
printf "%s\t%s\n", $seen, $ip;
};
}' < <(zcat /var/log/syslog*)
它会构建一个哈希数组 ( %IPs
),每次看到特定 IP 地址时都会进行计数。读取所有输入后,它按计数对哈希进行排序,并打印前 5 个。
顺便说一句,这zcat
不仅仅是/var/log/syslog*
因为系统日志和其他日志文件定期轮换和压缩是很常见的。