ubuntu 根据日期范围筛选日志文件条目

bz4sfanl  于 2023-02-18  发布在  其他
关注(0)|答案(4)|浏览(185)

我的服务器有异常高的CPU使用率,我可以看到Apache正在使用太多的内存。我有一种感觉,我正在被一个IP DOS-也许你可以帮助我找到攻击者?
我已经使用下面的行,找到10个最"活跃"的IP:

cat access.log | awk '{print $1}' |sort  |uniq -c |sort -n |tail

排名前五的IP对服务器的访问量是普通用户的200倍,但是我不知道这五个IP是经常访问者还是在攻击服务器。
是否有办法指定上述搜索的时间间隔,例如,过去两个小时或今天10 - 12之间?
干杯!

    • 2011年10月23日更新-我需要的命令:**

获取最近X小时内的条目[此处为两小时]

awk -vDate=`date -d'now-2 hours' +[%d/%b/%Y:%H:%M:%S` ' { if ($4 > Date) print Date FS $4}' access.log

获取最近X小时内最活跃的IP [此处为两小时]

awk -vDate=`date -d'now-2 hours' +[%d/%b/%Y:%H:%M:%S` ' { if ($4 > Date) print $1}' access.log | sort  |uniq -c |sort -n | tail

获取相对时间范围内的条目

awk -vDate=`date -d'now-4 hours' +[%d/%b/%Y:%H:%M:%S` -vDate2=`date -d'now-2 hours' +[%d/%b/%Y:%H:%M:%S` ' { if ($4 > Date && $4 < Date2) print Date FS Date2 FS $4}' access.log

获取绝对时间跨度内的条目

awk -vDate=`date -d '13:20' +[%d/%b/%Y:%H:%M:%S` -vDate2=`date -d'13:30' +[%d/%b/%Y:%H:%M:%S` ' { if ($4 > Date && $4 < Date2) print $0}' access.log

在绝对时间范围内获取最活跃的IP

awk -vDate=`date -d '13:20' +[%d/%b/%Y:%H:%M:%S` -vDate2=`date -d'13:30' +[%d/%b/%Y:%H:%M:%S` ' { if ($4 > Date && $4 < Date2) print $1}' access.log | sort  |uniq -c |sort -n | tail
093gszye

093gszye1#

是的,有多种方法可以做到这一点。下面是我将如何去做。对于初学者,不需要管道输出的猫,只需打开日志文件与awk

awk -vDate=`date -d'now-2 hours' +[%d/%b/%Y:%H:%M:%S` '$4 > Date {print Date, $0}' access_log

假设你的日志看起来像我的(他们是可配置的)比日期存储在字段4.和括号.我在上面做的是找到一切在过去2小时. Note the -d'now-2 hours'或翻译字面上现在减去2小时,这对我来说看起来像这样:[10/Oct/2011:08:55:23
因此,我所做的是存储两小时前的格式化值,并与字段4进行比较。条件表达式应该是直接的。然后,我打印日期,后跟输出字段分隔符(OFS --在本例中为空格),后跟整行$0。您可以使用前面的表达式,只打印$1(IP地址)

awk -vDate=`date -d'now-2 hours' +[%d/%b/%Y:%H:%M:%S` '$4 > Date {print $1}' | sort  |uniq -c |sort -n | tail

如果你想使用一个范围,指定两个日期变量并适当地构造你的表达式。
所以如果你想找到2- 4小时前的东西,你的表达式可能看起来像这样

awk -vDate=`date -d'now-4 hours' +[%d/%b/%Y:%H:%M:%S` -vDate2=`date -d'now-2 hours' +[%d/%b/%Y:%H:%M:%S` '$4 > Date && $4 < Date2 {print Date, Date2, $4} access_log'

下面是我回答的一个关于bash中日期的问题,您可能会发现这很有帮助。打印当前星期一的日期(bash中)

zbdgwd5y

zbdgwd5y2#

因为这是一个 * 常见 * perl任务

因为这与extract last 10 minutes from logfile不完全相同,extract last 10 minutes from logfile大约需要一段时间才能完成日志文件。
因为我需要它们,所以我(很快地)写下了这段话:

#!/usr/bin/perl -ws
# This script parse logfiles for a specific period of time

sub usage {
    printf "Usage: %s -s=<start time> [-e=<end time>] <logfile>\n";
    die $_[0] if $_[0];
    exit 0;
}

use Date::Parse;

usage "No start time submited" unless $s;
my $startim=str2time($s) or die;

my $endtim=str2time($e) if $e;
$endtim=time() unless $e;

usage "Logfile not submited" unless $ARGV[0];
open my $in, "<" . $ARGV[0] or usage "Can't open '$ARGV[0]' for reading";
$_=<$in>;
exit unless $_; # empty file
# Determining regular expression, depending on log format
my $logre=qr{^(\S{3}\s+\d{1,2}\s+(\d{2}:){2}\d+)};
$logre=qr{^[^\[]*\[(\d+/\S+/(\d+:){3}\d+\s\+\d+)\]} unless /$logre/;

while (<$in>) {
    /$logre/ && do {
        my $ltim=str2time($1);
        print if $endtim >= $ltim && $ltim >= $startim;
    };
};

这可以像这样使用:

./timelapsinlog.pl -s=09:18 -e=09:24 /path/to/logfile

用于在09:18到09:24之间打印日志。

./timelapsinlog.pl -s='2017/01/23 09:18:12' /path/to/logfile

用于从 * january 23th, 9h18'12" * 到 * 现在 * 的打印。
为了减少perl代码,我使用了-s开关来允许从命令行自动分配变量:-s=09:18将填充包含09:18的变量$s。注意不要漏掉等号=和空格!

**注:**这包含两种不同的 regex,用于两种不同的日志标准。如果您需要不同的日期/时间格式解析,请发布您自己的regex或发布日志文件中格式化日期的示例

^(\S{3}\s+\d{1,2}\s+(\d{2}:){2}\d+)         # ^Jan  1 01:23:45
^[^\[]*\[(\d+/\S+/(\d+:){3}\d+\s\+\d+)\]    # ^... [01/Jan/2017:01:23:45 +0000]
rqmkfv5c

rqmkfv5c3#

如果有人遇到awk: invalid -v option,这里有一个脚本可以获取预定义时间范围内最活跃的IP:

cat <FILE_NAME> | awk '$4 >= "[04/Jul/2017:07:00:00" && $4 < "[04/Jul/2017:08:00:00"' | awk '{print $1}' | sort -n | uniq -c | sort -nr | head -20
ifmq2ha2

ifmq2ha24#

要在指定范围内精确解析access.log,在本例中仅解析最后10分钟(基于EPOCH,也称为 * 自1970/01/01以来的秒数)*:

输入文件:
172.16.0.3 - - [17/Feb/2023:17:48:41 +0200] "GET / HTTP/1.1" 200 123 "" "Mozilla/5.0 (compatible; Konqueror/2.2.2-2; Linux)"
172.16.0.4 - - [17/Feb/2023:17:25:41 +0200] "GET / HTTP/1.1" 200 123 "" "Mozilla/5.0 (compatible; Konqueror/2.2.2-2; Linux)"
172.16.0.5 - - [17/Feb/2023:17:15:41 +0200] "GET / HTTP/1.1" 200 123 "" "Mozilla/5.0 (compatible; Konqueror/2.2.2-2; Linux)"
Perl的一行程序:

使用可靠的Time::Piece时间解析器,使用strptime()p粗略日期,使用strftime()f化新日期。此模块安装在core(默认)中,不可靠的Date::Parse则不会出现此情况

$ perl -MTime::Piece -sne '
    my $t = localtime; my $now = $t->epoch;
    m!\[(\d{2}/\w+/\d{4}:\d{2}:\d{2}:\d{2})\s!;
    my $d = Time::Piece->strptime("$1", "%d/%b/%Y:%H:%M:%S");
    my $old = $d->strftime("%s");
    my $diff = (($now - $old) + $gap);
    if ($diff > $min and $diff < $max) {print}
' -- -gap=$((7*3600)) -min=0 -max=600 access.log
参数说明:个1米9英寸、1米10英寸、1米11英寸交换机
  • -gap$((7*3600))又称25200秒,是与UTC差距:+7小时(以秒🇹🇭为单位)(泰文TZ)¹
  • -min自打印日志匹配行以来的最小秒数
  • -max打印日志匹配行之前的最大秒数
  • 要了解差距,请查看:

乌尔

$ LANG=C date
Fri Feb 17 15:50:13 +07 2023

+07是差距。
这样,您就可以使用此代码段在精确的秒范围内进行过滤。

示例输出
172.16.0.3 - - [17/Feb/2023:17:48:41 +0200] "GET / HTTP/1.1" 200 123 "" "Mozilla/5.0 (compatible; Konqueror/2.2.2-2; Linux)"

相关问题