这是我的第一篇帖子所以请耐心等待我,我想计算与ssh日志文件不同的时间,其格式如下
Jan 10 hr:min:sec Failed password for invalid user root from "ip" port xxx ssh2
Jan 10 hr:min:sec sshd[]: User root from "ip" not allowed because none of user's groups are listed in AllowGroups
当用户在10分钟内未能登录x次时,脚本会发出警报,有什么可以教我怎么做?
谢谢!
答案 0 :(得分:0)
您的规范有点含糊不清 - 可能在您的日志文件中会有两行以上 - 您想要连续行之间的时差吗?您是否希望解析一行搜索关键字(例如“登录失败”),然后将时间差分别解析为另一条线?
由于我无法判断你提供的是什么,我只是假设文件中有两行在每行的开头都有一个日期,你想要这些日期之间的时差。然后你可以操纵做你想做的事。或者,添加到您的问题并准确定义“登录失败”是什么。
有很多方法可以对这只猫进行皮肤处理,但我更喜欢DateTime::Format::Strptime中的strptime
函数,该函数被描述为;
对于DateTime,该模块实现了大部分strptime(3),即与strftime(3)相反的POSIX函数。虽然strftime采用DateTime和模式并返回一个字符串,但strptime接受一个字符串和一个模式并返回相关的DateTime对象。
这将如上所述;
use v5.12;
use DateTime::Format::Strptime;
my $logfile = "ssh.log";
open(my $fh, '<', $logfile) or die "$logfile: $!";
my $strp = DateTime::Format::Strptime->new(
pattern => '%h %d %T ',
time_zone => 'local',
on_error => 'croak',
);
my $dt1 = $strp->parse_datetime(scalar <$fh>);
my $dt2 = $strp->parse_datetime(scalar <$fh>);
my $duration = $dt2->subtract_datetime_absolute($dt1);
say "Number of seconds difference is: ", $duration->seconds ;
#
# Input
# Jan 10 14:03:18 Failed password for invalid user root from "ip" port xxx ssh2
# Jan 10 14:03:22 sshd[]: User root from "ip" not allowed because none of user's groups are listed in AllowGroups
#
# Outputs:
# Number of seconds difference is: 4
更全面的答案(做出更多假设)如下:
use v5.12;
use DateTime::Format::Strptime;
use DateTime::Duration;
my $logfile = "ssh.log";
my $maximum_failures_allowed = 3 ;
my $minimum_time_frame = 10 * 60; # in seconds
my $limit = $maximum_failures_allowed - 1 ;
# The following is a list of rules indicating a
# failed login for the username captured in $1
my @rules = (
qr/Failed password for user (\S+) / ,
qr/User (\S+) from [\d\.]+ not allowed/
);
my $strp = DateTime::Format::Strptime->new(
pattern => '%h %d %T ',
time_zone => 'local',
on_error => 'croak',
);
my %usernames ;
open(my $fh, '<', $logfile) or die "$logfile: $!";
while (<$fh>) {
for my $rx (@rules) {
if ( /$rx/ ) {
# rule matched -> login fail for $1. Save log line.
my $user = $1 ;
push @{ $usernames{$user} } , $_ ;
# No point checking other rules...
last ;
}
}
}
close $fh ;
for my $user (keys %usernames) {
my @failed_logins = @{ $usernames{$user} };
# prime the loop; we know there is at least one failed login
my $this_line = shift @failed_logins ;
while ( @failed_logins > $limit ) {
my $other_line = $failed_logins[ $limit ] ;
my $this_time = $strp->parse_datetime($this_line) ;
my $other_time = $strp->parse_datetime($other_line) ;
# this produces a DateTime::Duration object with the difference in seconds
my $time_frame = $other_time->subtract_datetime_absolute( $this_time );
if ($time_frame->seconds < $minimum_time_frame) {
say "User $user had login failures at the following times:" ;
print " $_" for $this_line, @failed_logins[ 0 .. $limit ] ;
# (s)he may have more failures but let's not labour the point
last ;
}
# Here if user had too many failures but within a reasonable time frame
# Continue to move through the array of failures checking time frames
$this_line = shift @failed_logins ;
}
}
exit 0;
掌握这些数据;
Jan 10 14:03:18 sshd[15798]: Failed password for user root from "ip" port xxx ssh2
Jan 10 14:03:22 sshd[15798]: User root from 188.124.3.41 not allowed because none of user's groups are listed in AllowGroups
Jan 10 20:31:12 sshd[15798]: Connection from 188.124.3.41 port 32889
Jan 10 20:31:14 sshd[15798]: Failed password for user root from 188.124.3.41 port 32889 ssh2
Jan 10 20:31:14 sshd[29323]: Received disconnect from 188.124.3.41: 11: Bye Bye
Jan 10 22:04:56 sshd[25438]: Connection from 200.54.84.233 port 45196
Jan 10 22:04:58 sshd[25438]: Failed password for user root from 200.54.84.233 port 45196 ssh2
Jan 10 22:04:58 sshd[30487]: Received disconnect from 200.54.84.233: 11: Bye Bye
Jan 10 22:04:59 sshd[21358]: Connection from 200.54.84.233 port 45528
Jan 10 22:05:01 sshd[21358]: Failed password for user root from 200.54.84.233 port 45528 ssh2
Jan 10 22:05:02 sshd[2624]: Received disconnect from 200.54.84.233: 11: Bye Bye
Jan 10 22:05:29 sshd[21358]: Connection from 200.54.84.233 port 45528
Jan 10 22:05:30 sshd[21358]: Failed password for user root from 200.54.84.233 port 45528 ssh2
Jan 10 22:05:33 sshd[2624]: Received disconnect from 200.54.84.233: 11: Bye Bye
Jan 10 22:06:49 sshd[21358]: Connection from 200.54.84.233 port 45528
Jan 10 22:06:51 sshd[21358]: Failed password for user root from 200.54.84.233 port 45528 ssh2
Jan 10 22:06:51 sshd[2624]: Received disconnect from 200.54.84.233: 11: Bye Bye
...它产生了这个输出;
User root had login failures at the following times:
Jan 10 22:04:58 sshd[25438]: Failed password for user root from 200.54.84.233 port 45196 ssh2
Jan 10 22:05:01 sshd[21358]: Failed password for user root from 200.54.84.233 port 45528 ssh2
Jan 10 22:05:30 sshd[21358]: Failed password for user root from 200.54.84.233 port 45528 ssh2
Jan 10 22:06:51 sshd[21358]: Failed password for user root from 200.54.84.233 port 45528 ssh2
请注意,日志文件数据中不存在时区和/或偏移量 - 因此,此脚本无法在您输入或保留“夏令时”的当天正常工作。