我正在运行这个命令来从服务器的auth.log获得一个失败的login尝试logging,它运作良好:
sudo cat /var/log/auth.{log,log.1} | grep 'Failed password' | grep sshd | awk '{print $1,$2}' | sort -k 1,1M -k 2n | uniq -c
但问题是 – 就像世界上的每一台服务器 – 我有一些由日志旋转创build的GZip压缩文件,不会被这个命令parsing:
-rw-r----- 1 syslog adm 7822722 Oct 31 13:44 /var/log/auth.log -rw-r----- 1 syslog adm 12532511 Oct 25 06:59 /var/log/auth.log.1 -rw-r----- 1 syslog adm 2250939 Oct 18 06:55 /var/log/auth.log.2.gz -rw-r----- 1 syslog adm 2139669 Oct 11 07:06 /var/log/auth.log.3.gz -rw-r----- 1 syslog adm 2769919 Oct 4 06:54 /var/log/auth.log.4.gz
为了解决这些问题,我有一个使用zcat而不是cat的命令的变体,但是运行两个命令来获取这些数据是有点麻烦的。 有什么办法可以将cat和zcat命令组合成一个命令,这样我就可以得到组合的结果了吗? 我知道我可以编写一些Bash脚本来通过压缩和未压缩的文件进行过滤,但是我在各种服务器上使用这个当前的单行程,并且我希望能够在需要时快速引用和使用单行程。
我一直在做一些安全审计和防火墙调整,并运行这个命令给我一个Ubuntu Linux机器上的auth.log文件的“失败的密码”尝试很好的auth.log :
sudo cat /var/log/auth.{log,log.1} | grep 'Failed password' | grep sshd | awk '{print $1,$2}' | sort -k 1,1M -k 2n | uniq -c
这很好用! 输出看起来像这样:
5909 Oct 18 13444 Oct 19 351 Oct 20 162 Oct 21 499 Oct 22 377 Oct 23 145 Oct 24 10897 Oct 25 76 Oct 26 54 Oct 27 310 Oct 28 1024 Oct 29 208 Oct 30 30 Oct 31
虽然这对于未压缩的日志效果很好,但是由于日志的旋转和压缩,总会有一些GZip压缩文件可以很好地logging下来。 所以我运行使用zcat的上述命令的这种变体:
sudo zcat -q /var/log/auth.log* | grep 'Failed password' | grep sshd | awk '{print $1,$2}' | sort -k 1,1M -k 2n | uniq -c
输出是这样的:
gzip: /var/log/auth.log: not in gzip format gzip: /var/log/auth.log.1: not in gzip format 10413 Sep 27 15977 Sep 28 12297 Sep 29 14438 Sep 30 23394 Oct 1 12912 Oct 2 15844 Oct 3 19697 Oct 4 15350 Oct 5 12358 Oct 6 12692 Oct 7 8377 Oct 8 10875 Oct 9 565 Oct 10 16027 Oct 11 10422 Oct 12 6808 Oct 13 26891 Oct 14 9493 Oct 15 5138 Oct 16 9415 Oct 17 2226 Oct 18
正如你所看到的,输出在工作时会起作用,但是如果这个命令的cat和zcat变体可以简单地合并成一个命令,那将会很好。 如何做到这一点?
奖励积分:
这些并不是关键问题,但如果能以某种方式解决问题,那将会很好:
zcat输出的顶部,有两个zcat尝试处理两个未压缩文件的错误。 抑制这将是很好的。 cat和zcat命令如何显示10月18日的数据; 日志轮换发生的一天。 有没有办法在命令中加上这两个值? 如果没有,我没有两个10月18日的数据与不同的值我不得不手动加起来。 可以使用zgrep ,如果需要的话可以解压缩,因此可以使用直接文本和压缩input。 同样,grep / zgrep可以直接处理多个文件,这是因为混合压缩和文本到标准input并不总是按照预期工作。 在grep输出中使用-h或--no-filename 。
sudo zgrep -h 'Failed password' /var/log/auth.* | grep sshd | awk '{print $1,$2}' | sort -k 1,1M -k 2n | uniq -c
手册页:
ZGREP(1) ZGREP(1) NAME zgrep - search possibly compressed files for a regular expression SYNOPSIS zgrep [ grep_options ] [ -e ] pattern filename... DESCRIPTION Zgrep invokes grep on compressed or gzipped files. All options specified are passed directly to grep. If no file is specified, then the standard input is decompressed if necessary and fed to grep. Otherwise the given files are uncompressed if necessary and fed to grep. If the GREP environment variable is set, zgrep uses it as the grep program to be invoked. AUTHOR Charles Levert ([email protected]) SEE ALSO grep(1), gzexe(1), gzip(1), zdiff(1), zforce(1), zmore(1), znew(1)
虽然每次input都很难,但你可以这样做:
for log in /var/log/auth.log*; do if ! sudo zcat "$log" 2>/dev/null; then sudo cat "$log"; fi; done | grep 'Failed password' | grep sshd | awk '{print $1,$2}' | sort -k 1,1M -k 2n | uniq -c
可能最好为cat部分创build一个函数,如下所示:
getLogs() { for log in /var/log/auth.log*; do if ! sudo zcat "$log" 2>&/dev/null; then sudo cat "$log" fi done }
那么你的命令可以
getLogs | grep 'Failed password' | grep sshd | awk '{print $1,$2}' | sort -k 1,1M -k 2n | uniq -c
或者你可以使整个事情成为一个function:
getSSHFailures() { for log in /var/log/auth.log*; do if ! sudo zcat "$log" 2>/dev/null; then sudo cat "$log" fi done | grep 'Failed password' | grep sshd | awk '{print $1,$2}' | sort -k 1,1M -k 2n | uniq -c }
那你就打电话
getSSHFailures
然后你可以在你的.bashrc定义这个函数,并且在你启动的每个shell中都有这个函数
此外,这也应该解决您的观察有关错误尝试zcat非压缩文件(因为我们redirectzcat错误到/dev/null ),摆脱重复的条目,因为我们打印所有的结果作为一个单一的在处理它们之前stream。
最后, awk实际上可以为我们做模式匹配,所以我们也可以去掉这两个grep :
getSSHFailures() { for log in /var/log/auth.log*; do if ! sudo zcat "$log" 2>/dev/null; then sudo cat "$log" fi done | awk '/sshd.*Failed password/ {print $1,$2}' | sort -k 1,1M -k 2n | uniq -c }